Matthew Berman
Matthew Berman

Reputation: 8631

How do I set a join model's attribute on the fly when creating a relationship?

I have a has_many :through relationship between users and projects via an ownership join model. I want to be able to set an attribute of the ownership model while creating a relationship between a user and a new project. Here is what I have so far:

def create
    @project = Project.new(params[:project])
    if @project.save
      current_user.projects << @project
      flash[:success] = "Project created!"
      redirect_to @project
    else
      flash[:error] = "Project not created."
    end
  end

Basically, I don't know how to set the value "owner_type" in the ownership model when creating a new project for a given user since I don't directly mention the ownership join model in the project creation controller. How do I do that?

Here is my ownership (join) model:

class Ownership < ActiveRecord::Base
  attr_accessible :owner_type

  belongs_to :project
  belongs_to :user

  validates :user_id, :presence => true

  validates :project_id, :presence => true

  validates :owner_type, :presence => true

end

and my User model:

class User < ActiveRecord::Base
  attr_accessible :name, :email, :admin, :projects

  has_many :ownerships
  has_many :projects, :through => :ownerships

  accepts_nested_attributes_for :projects

and my Project model:

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

      has_many :ownerships
      has_many :users, :through => :ownerships

Upvotes: 3

Views: 1785

Answers (2)

sled
sled

Reputation: 14625

The key is that you build (not create) the association before you hit @project.save when you hit save the project is persisted first and if it was persisted successfully, the ownership will be created too.

def create
  @project = Project.new(params[:project])
  @project.ownerships.build(:user => current_user, :owner_type => 'chief')

  if @project.save
    flash[:success] = "Project created!"
    redirect_to @project
  else
    flash[:error] = "Project not created."
  end
end

Upvotes: 3

Matthew Berman
Matthew Berman

Reputation: 8631

EDIT: This didn't actually work for me.

In my user model I allow for nested attributes with this line:

accepts_nested_attributes_for :projects

Then, in my projects#create controller action, I nested an attribute while creating the association between the user and the new project as so:

current_user.ownerships.create(:owner_type => 'designer', :project => @project)

To be honest I'm not sure exactly why this works but it does. Would be awesome for someone else to explain it.

Upvotes: 1

Related Questions