Thanks Jeremy! The opts[:join_plans] was the trick I was looking for :)
Cheers!
dave
On Monday, October 7, 2013 9:29:03 AM UTC-7, Jeremy Evans wrote:
>
> On Monday, October 7, 2013 9:07:07 AM UTC-7, Dave Bradford wrote:
>
>> Given the following models:
>>
>> class Plan < Sequel::Model
>> one_to_many :user_plans
>> end
>>
>> class User < Sequel::Model
>> one_to_many :plans, class: "UserPlan"
>> end
>>
>> class UserPlan < Sequel::Model
>> many_to_one :user
>> many_to_one :plan
>> end
>>
>>
>>
>> I'd like to have "chainable" filters on UserPlan that filter on fields
>> from Plan. For example:
>>
>> class UserPlan < Sequel::Model
>> dataset_module do
>> def visible
>> inner_join(:plans, id: :plan_id).where(plans__type: "hidden")
>> end
>>
>> def for_sku(sku)
>> inner_join(:plans, id: :plan_id).where(plans__sku: sku)
>> end
>> end
>>
>>
>>
>> However, attempting to chain the filters together joins "plans" twice
>> resulting in DB error (using Postgres). Example chained filters:
>>
>>
>> UserPlan.visible.for_sku("123")
>>
>>
>>
>> What would be best-practice for creating chainable filters for joined
>> tables?
>>
>
> What I would probably do in my own code is be more explicit about the
> joining, with an API like:
>
> UserPlan.join_plans.visible.for_sku("123")
>
> Basically, require join_plans be called before visible for for_sku.
>
> However, if you want to keep it implicit, you can use introspection on
> opts[:join] to see if the table has already been joined, and not do the
> join in that case. You can also do something simpler, just recording
> whether the table has already been joined:
>
> class UserPlan < Sequel::Model
> dataset_module do
> def join_plans
> opts[:join_plans] ? clone : inner_join(:plans, id:
> :plan_id).clone(:join_plans=>true)
> end
> def visible
> join_plans.where(plans__type: "hidden")
> end
> def for_sku(sku)
> join_plans.where(plans__sku: sku)
> end
> end
> end
>
> 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 http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/groups/opt_out.