create_table "podcasts", :force => true do |t|
t.boolean "use_show_name", :default => true
As you can see above that each podcast belongs to a show. I also have a form for this model and in the name field I want to display the name of the podcast unless "use_show_name" is true then I want to display the name of the show that this podcast belongs to.
<%= text_field :podcast, :name, :class => "text", :disabled => @podcast.use_show_name %>
I don't want to put this logic in the ERB template but instead I want to put it in the model so that anyone that calls Podcast.name will get the appropriate value depending on the "use_show_name".
class Podcast < ActiveRecord::Base
return self.use_show_name ? self.show.name : read_attribute(:name)
alias_method :name_before_type_cast, :name
So there a few things going on above.
- We override the "name" method by simply implementing it. This works because ActiveRecord using method_missing to implement it's "name" getter but since there is now a "name" method, method_missing will not be invoked.
- In the method we check "use_show_name" to see what value to return. If it is true we get the value from the show object. Otherwise, we call read_attribute to get the value of the name attribute that stored in the DB.
- Lastly, we alias the name method as "name_before_type_cast" since this is the method that is called by FormHelper.text_field. ActiveRecord form helpers call the before_type_cast so that they can get the string value of the attribute but we want it to get the value from our "name" method.