On Monday, October 6, 2014 12:36:27 PM UTC-7, Jarrod Manzer wrote:
>
> I have a situation that I would like advice on. I created a schema that 
> has lookup tables with several extra fields (created_at, rediscovered_at 
> and 'type'). These extra fields are needed as we have to know when the 
> associations came into existence and when was it last 'noticed' by our 
> discovery system. The two models being associated can have very different 
> timestamps than the association itself. The 'type' column is simply the 
> type of association as there are several kinds (primary, secondary, gateway 
> etc). Having implemented this schema I mucked up the natural add_* methods 
> and was getting various errors when I called them. I created a model for 
> the association itself and then overwrote the add methods with my own that 
> can handle the extra logic needed but I wonder what the ramifications will 
> be? Have I made a mistake here or is it ok to change those add methods?
>
> class Interface < Sequel::Model
>   many_to_many :ipaddresses, join_table: :ipaddress_bindings
> end
>
> class Ipaddress < Sequel::Model
>   many_to_many :interfaces, join_table: :ipaddress_bindings
> end
>
> DB[:ipaddress_bindings].columns
> => [:id, :ipaddress_id, :interface_id, :created_at, :rediscovered_at, 
> :type]
>
> And here is the additional model and rewritten add_ipaddress_binding method
>
> class IpaddressBinding < Sequel::Model
>   many_to_one :interface
>   many_to_one :ipaddress
> end
>
> def add_ipaddress_binding(ipaddress, options)
>   IpaddressBinding.create(
>     options.merge(
>       interface_id: self.id,
>       ipaddress_id: ipaddress.id,
>     )
>   )
> end
>

The problem with this is that the add_* association methods should handle 
things like caching and callbacks, so you almost never want to override 
them directly.

You could use the :adder association option for this:

  Interface.many_to_many :ipaddresses, :adder=>proc{|ip, opts| 
IpaddressBinding.create(opts.merge(:interface_id=>id, 
:ipaddress_id=>ip.id))}
 
But a better option is just to add an association to the join table model, 
and use that

  Interface.one_to_many :ipaddress_bindings
  Interface.add_ipaddress_binding(:ipaddress=>ip, ...)

So the new method on Interface looks like ...
> add_ipaddress_binding(ipaddress, options)
>
> and the old method on Interface looked like ...
> add_ipaddress_binding(o, *args)
>

There is probably an error here, as Interface.many_to_many :ipaddresses is 
going to add add_ipaddress, not add_ipaddress_binding. 

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/d/optout.

Reply via email to