Question

What is the correct way to do the following in Rails 4? I have a form that takes in a string and some other parameters for a particular model, let's say Foo. This model has an association to another model,

class Foo < ActiveRecord::Base
  belongs_to :bar
end

I want to create a new Bar from the given string, assuming a Bar with that name doesn't already exist in the database.

My initial approach was to do this at the controller level, essentially grabbing the name from the params, and then attempting to create a object from it and mutate the original params to include the new object instead of the original string. But I'm realizing that that's not very idiomatic Rails and that I should instead be doing this entirely at the model level.

So how would I accomplish what I want to do at the model level? I am thinking I need a transient attribute and some kind of before_validation filter, but I am not very familiar with Rails. Any ideas?

Was it helpful?

Solution

Not sure to understand correctly what are you trying to do but you might want to take a look at rails nested attributes.

You would have a Foo class like the following:

class Foo < ActiveRecord::Base
  has_one :bar

  accepts_nested_attributes_for :bar
end

class Bar < ActiveRecord::Base
  belongs_to :foo
end

And you could create a new Bar instance directly associated to Foo like so:

foo = Foo.new(bar_attributes: { name: "Bar's name" })
foo.bar.name
#=> "Bar's name"

OTHER TIPS

Why do you need to mutate the params? IMO this should be done at the controller level but without changing any params at all.

class FoosController

  before_filter :set_foo
  before_filter :set bar

  def update
    @foo.bar = @bar
    @foo.update(foo_params)
    respond_with @foo
  end

  private 

    def set_foo
      @foo = Foo.find(params[:id])
    end

    def set_bar
      @bar = # create/find your Bar from the params here
    end

    def foo_params
      params.require(:foo).permit(...)
    end

end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top