nested attributes with belongs_to

Here is my model looks like:-

Model: Movie
has_many :songs

Model: Song

belongs_to :movie

I have a songs/new form which contains song name and movie name input field. If movie name does not exist it should create a new one else it should use already existing one. So this I will come to know only after user enter in movie name field.

Can I achieve this using nested attributes of rails 3?

Note: I can able to implement the same in has_many association but not in this case.

Thanks!

Butu

Butu,

You should look at before_create in ActiveRecord. I think it would be
better if you put on in your Song Model that calls private function to
check whether the passed in Movie name exists or not. If it doesn't,
create it and if it does exist do nothing.

Thanks,

B.

Thanks Bryan for your reply.

For first part of my problem, I am able to figure out the nested attributes with belongs_to.

For second part, I am looking for Rails way solution to my problem.

Using nested attribute. I can able to create Movie if it does not exist. And able to associate it with song model (movie_id populated correctly) work really good by rails way. I want this behavior.

But when movie already exist. I want to associate that movie id with the new song to be created using accepts_nested_attributes_for.

Thanks!

Butu

Thanks Bryan for your reply.

For first part of my problem, I am able to figure out the nested attributes with belongs_to.

For second part, I am looking for Rails way solution to my problem.

Using nested attribute. I can able to create Movie if it does not exist. And able to associate it with song model (movie_id populated correctly) work really good by rails way. I want this behavior.

But when movie already exist. I want to associate that movie id with the new song to be created using accepts_nested_attributes_for.

you can’t. accepts_nested_attributes_for doesn’t work on belongs_to attribute.

Hello Jim,

Thanks for your reply.

I can able to do accepts_nested_attributes with belongs_to

@song.build_movie

use this either in action or before the form and use fields_for. This will create the new movie record and insert movie_id in song model as well.

You don't need to use nested attributes for that. You can achieve the
same result with a pretty simple virtual attribute:

class Song < ActiveRecord::Base
  belongs_to :movie

  def movie_name=(name)
    @movie_name = name
    self.movie = Movie.find_or_initialize_by_name(name)
  end

  def movie_name
    @movie_name
  end
end

And then on your form:

= form_for @song do |form|
  = form.text_field :movie_name

Reu, thanks a lot!! this is exactly what I want.

Facing one problem when I am using accepts_nested_attributes_for and has_many. This is working in rails way and able to insert record into songs, people and people_song table correctly. But again I want to use similar logic find and initilize. But in that case I may need to insert into people_song table manually. Any thoughts on this?

Thanks!

Butu