= New Features * A one_through_one association type has been added. This is similar to the many_to_many association type in that it uses a join table, but it returns a single record instead of an array of records. This is designed for cases where the foreign key in the join table that references the current table has a unique constraint, or where you want to use an order to just pick the first matching record. Similarly, the many_through_many plugin now also offers a one_through_many association. * An association_join method has been added to model datasets, for setting up joins based on associations. This basically does the same join that eager_graph would do, but does not make the other changes that eager_graph makes. Unlike eager_graph (which uses LEFT OUTER JOINs by default), association_join uses INNER JOINs, but there are also association_*_join methods (e.g. association_left_join) for using different join types. Similar to eager_graph, you can use cascading of associations or multiple associations. Album.association_join(:artist, :tracks) Artist.association_left_join(:albums=>:tracks) * Dataset#eager_graph_with_options has been added for model datasets. It currently supports a :join_type option, for overriding the type of join to use on a per-call basis, as well as a :limit_strategy option. The API is similar to eager_graph, except that the associations to eagerly load are passed in as a single argument, and it takes an options hash. The :limit_strategy option works similarly to the :eager_limit_strategy option when eagerly loading. If set to true and the database supports window functions, it will join the current dataset to a subquery that uses a window function to correctly restrict the join to only those objects that fall within the association's limit/offset. The :limit_strategy option is not on by default. It is possible for it to perform significantly worse than the default strategy (which uses array slicing in ruby). The :limit_strategy significantly changes the SQL used, and can change the results of the query if any filters/orders related to the association are used. It's recommended you only use the :limit_strategy option if you are experiencing a bottleneck and you have benchmarked that it is faster and still produces the desired results. Artist.eager_graph_with_options(:first_10_albums, :limit_strategy=>true) # SELECT artists.id, artists.name, # first_10_albums.id AS first_10_albums_id, # first_10_albums.name AS first_10_albums_name, # first_10_albums.artist_id, # first_10_albums.release_date # FROM artists # LEFT OUTER JOIN ( # SELECT id, name, artist_id, release_date # FROM ( # SELECT *, row_number() OVER (PARTITION BY tracks.album_id) # AS x_sequel_row_number_x # FROM albums # ) AS t1 WHERE (x_sequel_row_number_x <= 10) # ) AS first_10_albums ON (first_10_albums.artist_id = artists.id) * Dataset#full_text_search on PostgreSQL now supports :plain and :phrase options. :plain takes the search terms as a single string, and searches for rows where all terms are used. :phrase is similar to :plain, but also adds a substring search to ensure that the string given appears verbatim in the text. * A :graph_order association option has been added, for using a different order when using eager_graph. This is mostly designed for cases where :order should be qualified in other cases, but using a qualification breaks eager_graph because the correct qualifier is not known until runtime. * SQL::AliasedExpression#alias has been added as an alias for #aliaz. = Other Improvements * Sequel will now automatically use an eager limit strategy for *_one associations that use an :order option. For associations that are truly one-to-one, an :order option is not needed, so it only makes sense to have an :order option if the association could theoretically return multiple results (in which case an eager limit strategy is helpful). * The queries that Sequel uses to filter by associations when those associations have conditions are now simpler and easier for the database to execute. * The queries that Sequel uses for dataset associations now handle cases where unqualified identifiers were used in the receiving dataset that would be made ambiguous by a join. * A limit strategy is now used when filtering by associations if the association has a limit and the database supports window functions. This allows Sequel to setup a correct filter in such cases. Artist.where(:first_10_albums=>Album[1]).all # SELECT * # FROM artists # WHERE (artists.id IN ( # SELECT albums.artist_id # FROM albums # WHERE ((albums.artist_id IS NOT NULL) AND (albums.id IN ( # SELECT id FROM ( # SELECT albums.id, row_number() OVER # (PARTITION BY albums.artist_id ORDER BY release_date) # AS x_sequel_row_number_x # FROM albums # ) AS t1 # WHERE (x_sequel_row_number_x <= 10) # )) AND (albums.id = 1)))) * A limit strategy is now used in the dataset_associations plugin if the association has a limit and the database supports window functions. This makes the resulting datasets return correct results. Artist.first_10_albums # SELECT * # FROM albums # WHERE ((albums.artist_id IN ( # SELECT artists.id FROM artists) # ) AND (albums.id IN ( # SELECT id FROM ( # SELECT albums.id, row_number() OVER # (PARTITION BY albums.artist_id ORDER BY release_date) # AS x_sequel_row_number_x # FROM albums # ) AS t1 # WHERE (x_sequel_row_number_x <= 10) # ))) # ORDER BY release_date * You can now pass symbols with embedded qualifiers or aliases, as well as SQL::Identifier, SQL::QualifiedIdentifier, and SQL::AliasedExpression objects as the first argument to Dataset#graph. * The nested_attributes plugin now automatically handles presence validations on foreign keys when creating associated objects. It now sets the foreign key value (or a placeholder value) before validating such objects. * Offsets on *_one associations are now respected when using eager_graph. * eager graphing *_many associations with offsets no longer breaks if there are no associated results. * Database#register_array_type in the pg_array extension now works correctly if there is no existing scalar conversion proc for the type. * Unique, foreign key, and not null constraint violations are now recognized correctly on SQLite 3.8.2+. * The odbc adapter now returns fractional seconds in timestamps. * The obdc/mssql adapter now inputs timestamps with 3 decimal places. = Backwards Compatibility * The private Model.apply_window_function_eager_limit_strategy method has been removed.