Rudi
Rudi

Reputation: 1587

rails model assignment with has_many :through

I just can't figure out how to create a relation with a join table. I've read all the posts about them, but the main error seems to be that in the join table to models should be singular, which I have. I just can seem to create the models correctly and assign them. I have projects with datasets, and projects can have multiple datasets, while a dataset can belong to multiple projects. A dataset can be active or not, which is why I need the has_many through instead of the has_many_and_belongs_to setup. My model definitions are:

class Project < ActiveRecord::Base
  attr_accessible :name, :user_id

  belongs_to :user
  has_many :activedatasets
  has_many :datasets, :through => :activedatasets

end


class DataSet < ActiveRecord::Base
  attr_accessible :name, :project_id, :filename, :tempfilename

  has_many :activedatasets
  has_many :projects, :through => :activedatasets

end


class ActiveDataSet < ActiveRecord::Base
  attr_accessible :active, :data_set_id, :project_id

  belongs_to :project
  belongs_to :dataset

end

When I create a new dataset I've got the project_id in the params, so I'm trying to setup the relationship like below:

class DataSetsController < ApplicationController
  def new
    @dataset = DataSet.new
    @dataset.activedatasets.project_id = params[:project_id]
  end
end

The error I'm getting seems famous:

NameError in DataSetsController#new

uninitialized constant DataSet::Activedataset

Can anybody point me in the right direction please?

Thanks for you attention.

Upvotes: 0

Views: 1793

Answers (1)

Paul Russell
Paul Russell

Reputation: 4747

You need to use:

has_many :active_data_sets
has_many :data_sets, :through => :active_data_sets

And in the DataSet model:

has_many :active_data_sets
has_many :projects, :through => :active_data_sets

Basically, rails expects you to use underscores to separate words in association names, and converts them to CamelCase. So active_data_sets becomes ActiveDataSet. Rails then uses this to work out which model class the association is with.

You also need to change your controller to this:

class DataSetsController < ApplicationController
  def new
    @dataset = DataSet.new
    @dataset.active_data_sets.build(:project_id => params[:project_id])
  end
end

Otherwise you'll get an error because you tried to set the project_id of the active_data_sets collection rather than creating a new ActiveDataSet.

Upvotes: 2

Related Questions