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.