On Saturday, December 2, 2017 at 8:10:06 PM UTC-8, Andrew Burleson wrote:
>
> I have an app where there are Writing Groups:
> - Each group can have many Users.
> - Users can have many books.
> - Users can submit a book to a group.
> - Books then proceed through several states, such as "pending review" ->
> "in review" -> "accepted" | "rejected", etc.
>
> The Group <-> Books relation is very simple to set up using a table
> `group_books` with the primary key (group_id, book_id).
>
> The basic associations are very easy to set up:
>
> class Group < Sequel::Model
> one_to_many :group_books
> many_to_many :books, join_table: :group_books
> end
>
> <3 Sequel!
>
> Now, using the group it would be helpful to filter books based on what
> state they're in, eg. rather than show me all books, show me all books that
> are pending review. In the database this means the group book's
> `review_status` column has the value `pending_review.`
>
> It's possible to declare that association like so:
>
> many_to_many :books_pending_review, join_table: :group_books, class: :Book
> , right_key: :book_id do |ds|
> ds.where(review_status: 'pending_review')
> end
>
> This works fine, but in practice I have some qualms with it:
>
> First, it duplicates knowledge. For instance, in the GroupBooks model I
> would want to have the following:
>
> dataset_module do
> def pending_review
> where(review_status: 'pending_review')
> end
> end
>
> Now, I can chain that association if I want to return the group book
> records, e.g.: `group.group_books.pending_review`, but that returns the
> join models, not the book models.
>
> I'd prefer that the enum values that define book states in the database be
> limited to the GroupBook class and be referenced via methods from the
> outside world.
>
> A secondary, less important concern, is that this ends up being very
> verbose if you have a large number of filtered associations in a full-size
> app.
>
Assuming that every association is basically the same other than the status
filter:
many:to_many :books, join_table: :group_books, class: :Book, right_key:
:book_id
%w'pending_review in_review accepted rejected'.each do |status|
many_to_many :"books_#{status}", :clone=>:books do |ds|
ds.where(review_status: status)
end
end
> So, is there a cleaner or better way to do this, ideally defining the
> filtered associations in one place (GroupBook) and simply referencing them
> (or chaining them) elsewhere?
>
Instead of making a many_to_many association, make a one_to_many to the
join model (GroupBook), and have that use the :eager/:eager_graph option to
also get the Book.
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.