Question

I GOT TWO PROBLEMS:

-I'm stuck with creating a project which includes nested attributes for :position

-I got it nearly working for editing the project details plus the :position attribute, but the fields_for :assigned_projects ads all the fields for all users who are assigned to the project.

I have 3 Models:

class User < ActiveRecord::Base
  has_many :assigned_projects
  has_many :projects, :through => :assigned_projects

  has_many :created_projects, :class_name => "Project", :foreign_key => :creator_id
end

class Project < ActiveRecord::Base
  belongs_to :user
  has_many :assigned_projects
  has_many :users, :through => :assigned_projects
  belongs_to :creator, :class_name => "User", :foreign_key => :creator_id

  attr_accessible :name, :controlled, :currency, :creator_id, :assigned_projects  
  accepts_nested_attributes_for :assigned_projects#, :allow_destroy => true
end

class AssignedProject < ActiveRecord::Base
  belongs_to :user,    class_name: "User"
  belongs_to :project, class_name: "Project"

  attr_accessible :project_id, :user_id, :position, :project, :user, :user_attributes
  accepts_nested_attributes_for :user
end

Each User can create a Project and is the Projects.creator Each Project has_many Users through the join model Assigned_Project

Each User can have a different position in the project, so I want to save the :position in the join model AssignedProject.

if a user creates a Project, he should be able to edit the project attributes PLUS the :position attribute of the new join model.

Now the Form field for New.Project and Edit.Project

/project/new.htm.erb

<%= form_for( setup_new_project(@project) ) do |f| %>

    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.fields_for :assigned_projects do |ff| %>
        <%= ff.label :position %>
        <%= ff.text_field :position%>
    <% end %>

    <%= f.submit "Add Project", class: "" %>                    
<% end %>


/project/edit.htm.erb

<%= form_for( setup_project(current_project) ) do |f| %>

    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.fields_for :assigned_projects do |ff| %>
        <%= ff.label :position %>
        <%= ff.text_field :position%>
    <% end %>

    <%= f.submit "Update Project", class: "" %>
<% end %>

And I have the following setup methods as described in this article: http://www.sitepoint.com/complex-rails-forms-with-nested-attributes/

module FormHelper
    def setup_project(project)
        project.assigned_projects ||= AssignedProject.new
        project
    end

    def setup_new_project(project)
        project.assigned_project = AssignedProject.new
        project
    end

end

I hope the problem is clear enough.

for creating a new project the current error message is:

undefined method `assigned_project='

15:             <%= render 'shared/user_sidebar_menu' %>
16: 
17:             <div class="span4 offset1">
18:                 <%= form_for( setup_new_project(@project) ) do |f| %>
19: 
20:                     <%= render 'shared/error_messages', object: f.object %>
21: 

UPDATE: added projects_controller.rb

projects_controller.rb

class ProjectsController < ApplicationController

    def new
        @project = Project.new
    end

    def create
        @project = Project.new(params[:project])
        @project.creator = current_user
        if @project.save
            current_user.assigned_projects.create(project: @project)
            redirect_to current_user
        else
            render 'new'
        end
    end
end
Was it helpful?

Solution

Update setup_new_project method as below:

   def setup_new_project(project)
        project.assigned_projects.build ## Updated this line
        project
    end

Use project.assigned_projects(Notice plural) instead of project.assigned_project(Notice singular WRONG).

User and AssignedProject model are in a 1-M relationship. So, you get dynamic method assigned_projects=(Notice plural), you are getting error as you called assigned_project=(Notice singular) which does not exist.

UPDATE

undefined method each for <AssignedProject:0x007ff7aa55b528>

Use project.assigned_projects.build instead of project.assigned_project = AssignedProject.new.

UPDATE 2

You are approaching this incorrectly. The form helpers are totally not required. All you need to do is update the new and create actions as below:

def new
    @project = Project.new
    @project.assigned_projects.build
end

and update the form_for in both new and edit view's as below:

<%= form_for(@project) do |f| %> 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top