Default values in join model

I have a has_many :through and I would like to take values from one
side and put them in the join model. Perhaps some code would be more
clear.

class Recipe < AR::Base
has_many :fermentable_ingredients
has_many :fermentables, :through => :fermentable_ingredients
end

class Fermentable < AR::Base
has_many :fermentable_ingredients
has_many :recipes, :through => :fermentable_ingredients
end

classFermentableIngredient < AR::Base
belongs_to :recipe
belongs_to :fermentable
end

Simple enough. When I assign a fermentable to a
fermentable_ingredienet, I would like to populate the
fermentable_ingredient with values in fermentable. Something like
this:

def fermentable=(f)
self.potential = f.potential if potential.nil?
self.color = f.color if color.nil?
super
end

I know this doesn’t work because the call to super fails.

Is there a clean way to do this?

Thanks,
–Dean
http://blog.brewsession.com/

On Feb 6, 1:58 pm, “Dean” [email protected] wrote:

classFermentableIngredient < AR::Base
belongs_to :recipe
belongs_to :fermentable
end

Simple enough. When I assign a fermentable to a
fermentable_ingredienet, I would like to populate the
fermentable_ingredient with values in fermentable. Something like
this:

Will this work?

class FermentableIngredient
before_save :copy_from_fermentable

protected
def copy_from_fermentable
if self.fermentable
self.potential ||= fermentable.potential
self.color ||= fermentable.color
end
end
end

Dan M.

On Feb 6, 12:37 pm, “Dan M.” [email protected] wrote:

    end
end

end

Dan M.

Thanks for the suggestion, but I want to do it before saving. Like
here:

class FermentableIngredientsController < ApplicationController
def new
@fermentable_ingredient = FermentableIngredient.new
@fermentable_ingredient.fermentable =
Fermentable.find( params[:fermentable_id] )
render
end
end

That way the form fields for @fermentable_ingredient will be
automatically filled out. As it is I have to call an extra method
before render to transfer the values.

–Dean

On Feb 6, 4:17 pm, “Dean” [email protected] wrote:

Thanks for the suggestion, but I want to do it before saving.

Try this:

classFermentableIngredient < AR::Base
belongs_to :recipe
belongs_to :fermentable

fermentable_with_copy=(f)
self.potential ||= f.potential
self.color ||= f.color
fermentable_without_copy=f
end
alias_method :fermentable_without_copy=, :fermentable=
alias_method :fermentable=, :fermentable_with_copy=
end

Dan M.

fermentable_without_copy=f

end
alias_method :fermentable_without_copy=, :fermentable=
alias_method :fermentable=, :fermentable_with_copy=
end

Dan M.

That is really close, except it does not assign the fermentable to
the ingredient.

./script/console

i = FermentableIngredient.new
=> #<FermentableIngredient…>
i.fermentable = Fermentable.find(1)
=> #<Fermentable:… “potential”=>“1.037”}>
i.potential
=> 1.037
i.fermentable.potential
NoMethodError: You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.potential
from (irb):5

i.fermentable
=> nil

Looks like this should work from the ruby-doc on alias_method
http://www.ruby-doc.org/core/classes/Module.html#M001706

alias_method :orig_fermentable=, :fermentable=
def fermentable=(f)
self.potential ||= f.potential
self.color ||= f.color
orig_fermentable = f
end

But it still does not assign the fermentable to the
fermentable_ingredient.

–Dean
http://blog.brewsession.com/

On Feb 6, 3:27 pm, “Dan M.” [email protected] wrote:

And the answer is:

alias_method :orig_fermentable=, :fermentable=

def fermentable=(f)
self.potential ||= f.potential
self.color ||= f.color
self.orig_fermentable = f
end

Thanks to Dan for the help

–Dean
http://blog.brewsession.com/