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.

Reply via email to