Rails override the default getter for a relation (owned by_to)

So, I know how to override the default recipients for attributes of an ActiveRecord object using

def custom_getter return self[:custom_getter] || some_default_value end 

I try to achieve the same, but for the association belongs. For example.

 class Foo < AR belongs_to :bar def bar return self[:bar] || Bar.last end end class Bar < AR has_one :foo end 

When I speak:

 f = Foo.last 

I would like the f.bar method f.bar return the last line, not nil if this relationship does not already exist.

However, this does not work. The reason is that self [: bar] is always undefined. This is actually self [: bar_id].

I can do something naive like:

 def bar if self[:bar_id] return Bar.find(self[:bar_id]) else return Bar.last end end 

However, this will always cause a db call, even if Bar has already been checked out, which is certainly not ideal.

Does anyone have an idea of ​​how I can relate, so the belongs_to attribute is only loaded once and has a default value if it is not set.

+43
ruby-on-rails activerecord default-value associations
Mar 23 '10 at 14:44
source share
3 answers

alias_method is your friend here.

 alias_method :original_bar, :bar def bar self.original_bar || Bar.last end 

How it works is that you use the bar as the source bar by default, and then implement your own version of bar. If calling original_bar returns nil, then you are returning the last instance of Bar.

+70
Mar 23 '10 at 14:48
source share

I found that using "super" is the best way

 def bar super || Bar.last end 

Hope this helps you: D

+11
Feb 20 '16 at 21:42
source share

Randy's answer is in place, but there is an easier way to write it using alias_method_chain:

 def bar_with_default_find self.bar_without_default_find || Bar.last end alias_method_chain :bar, :default_find 

This creates two methods - bar_with_default_find and bar_without_default_find and bar aliases to the with method. That way, you can explicitly call one or the other, or just leave the default values ​​as they are.

+10
Mar 09 '13 at 16:28
source share



All Articles