不会保存连接模型的嵌套属性。似乎缺少关系id。验证字段时添加以下错误消息:
* Assigned projects user can't be blank
* Assigned projects project can't be blank
提交的参数看起来像这样(<%= debug(params)%>)
--- !map:ActionController::Parameters
utf8: "\xE2\x9C\x93"
authenticity_token: HrF1NHrKNTdMMFwOvbYFjhJE1ltlKbuz2nsfBYYBswg=
project: !map:ActionController::Parameters
name: Peter Pan
assigned_projects_attributes: !map:ActiveSupport::HashWithIndifferentAccess
"0": !map:ActiveSupport::HashWithIndifferentAccess
position: Group Leader
currency: " Neverland Dollars"
commit: Add Project
action: create
controller: projects
我有3个型号,如下:
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 AssignedProject < ActiveRecord::Base
belongs_to :user, class_name: "User"
belongs_to :project, class_name: "Project"
attr_accessible :project_id, :user_id, :position, :project_attributes
accepts_nested_attributes_for :project
validates :user_id, presence: true
validates :project_id, presence: true
validates :position, presence: true
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, :creator_id, :currency :assigned_projects_attributes
accepts_nested_attributes_for :assigned_projects
validates :name, presence: true, length: { minimum: 3, maximum: 100 }
validates :currency, presence: true, length: { minimum: 1, maximum: 5 }
validates :creator_id, presence: true
end
因此每个用户都可以创建一个项目。他可以通过连接模型将任何用户添加到项目中。 每个项目属于一个用户分配。创建者和has_many用户通过assigned_projects
我想给项目的每个用户一个“位置”,该位置应该保存在连接模型中:assigned_project:position
Project控件看起来像这样:
class ProjectsController < ApplicationController
def new
@project = Project.new
@project.assigned_projects.build(user_id: current_user)
end
def create
@project = current_user.assigned_projects.build.build_project(params[:project])
@project.creator = current_user
if @project.save
redirect_to current_user
else
render 'new'
end
end
end
并且project / new.html.erb表单看起来像这样:
<%= form_for( @project ) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :assigned_projects do |ff| %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.label :currency %>
<%= f.text_field :currency %>
<%= f.submit "Add Project", class: "" %>
<% end %>
更新:当前控制器&amp;图
def create
@project = Project.new(params[:project])
if @project.save
redirect_to current_user
else
render 'new'
end
end
<%= form_for( @project ) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.hidden_field :creator_id, value: current_user.id %>
<%= f.fields_for :assigned_projects, @project.assigned_projects do |ff| %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.label :currency %>
<%= f.text_field :currency %>
<%= f.submit "Add Project", class: "" %>
<% end %>
答案 0 :(得分:0)
我认为您需要将@project.assigned_projects
操作中构建的对象集合new
传递给fields_for
:
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for :assigned_projects, @project.assigned_projects do |ff| %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.label :currency %>
<%= f.text_field :currency %>
<%= f.submit "Add Project", class: "" %>
如果我理解create
操作中的第一行,我认为您尝试重新构建项目assigned_projects
以便标记creator
属性!!
相反,你可以删除这一行并在嵌套for中放入一个隐藏字段,例如:
<%= ff.hidden_field :creator, current_user %>
所以你的控制器现在看起来非常基本:
def create
@project = Project.new(params[:prject])
if @project.save #nested objects will be saved automatically
redirect_to current_user
else
render 'new'
end
end
答案 1 :(得分:0)
build_project方法有什么作用? 我认为在你的控制器中你应该只有build,而不是build.build_project,所以这样:
@project = current_user.assigned_projects.build(params[:project])
如果build_project是用于创建参数的方法,那么
@project = current_user.assigned_projects.build(project_params)
对于rails 4,你需要这样的东西:
def project_params
params.require(:project).permit(:your_params)
end
对于rails 3,我认为你需要添加
attr_accessible :param1, :param2
项目模型中的表示您要设置的参数。
答案 2 :(得分:0)
通过删除连接表中的project_id和user_id的验证来解决问题&#34; AssignedProject&#34;
所以连接模型看起来像这样:
# Join Model AssignedProject
class AssignedProject < ActiveRecord::Base
belongs_to :user#, class_name: "User"
belongs_to :project#, class_name: "Project"
attr_accessible :project_id, :user_id, :position, :project, :project_attributes
accepts_nested_attributes_for :project
validates :position, presence: { message: " can't be blank." }
end
New和Create方法看起来像这样:
# Projects Controller
class ProjectsController < ApplicationController
def new
@project = Project.new
@project.assigned_projects.build(user_id: current_user)
end
def create
@project = Project.new(params[:project])
if @project.save
@project.assigned_projects.create(user_id: current_user)
redirect_to current_user
else
render 'new'
end
end
end
新方法视图中的表单如下所示:
<%= form_for( @project ) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.hidden_field :creator_id, value: current_user.id %>
<%= f.fields_for :assigned_projects, @project.assigned_projects do |ff| %>
<%= ff.hidden_field :project_id, value: @project %>
<%= ff.hidden_field :user_id, value: current_user.id %>
<%= ff.label :position %>
<%= ff.text_field :position%>
<% end %>
<%= f.label :currency %>
<%= f.text_field :currency %>
<%= f.submit "Add Project", class: "" %>
<% end %>