我的用户模型has_many响应。我正在尝试创建一个嵌套表单来创建一个具有三个子响应的新用户。我的代码看起来与Rails强制转换相同,但是虽然它会保存用户,但它不会保存它们的响应。任何人都可以看到有什么问题吗?
users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
3.times{@user.responses.build}
@responses = @user.responses
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user #todo: where do we want to redirect?
else
render 'new'
end
end
def show
@user = User.find(params[:id])
@responses = @user.responses
end
def index
@users = User.all
end
private
def user_params
params.require(:user).permit(:username, :email, :responses)
end
end
user.rb
class User < ActiveRecord::Base
attr_accessor :responses_attributes
has_many :responses, :dependent => :destroy
accepts_nested_attributes_for :responses#, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
before_save { self.email = email.downcase }
validates :username, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX } ,
uniqueness: {case_sensitive: false};
validates :responses, presence: true
end
response.rb
class Response < ActiveRecord::Base
belongs_to :user
validates_presence_of :user_id, :content
end
users / new.html.erb(表单)
<h1>This is a test form for adding Users with child Responses</h1>
<%= form_for @user do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.label :email %>
<%= f.text_field :email %>
<p>
<%= f.fields_for :responses do |builder| %>
<%= builder.label :content, "Response" %>
<%= builder.text_field :content %>
<% end %>
</p>
<%= f.submit "Submit" %>
<% end %>
编辑:
我已将Users控制器中的强参数更改为:
def user_params
params.require(:user).permit(:username, :email, responses_attributes: [:content])
end
我已将用户模型更新为:
class User < ActiveRecord::Base
has_many :responses, :dependent => :destroy
accepts_nested_attributes_for :responses#, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
before_save { self.email = email.downcase }
validates :username, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX } ,
uniqueness: {case_sensitive: false};
validates_associated :responses, presence: true
end
现在它仍然无法通过我的回复验证,也无法验证用户名和电子邮件的验证。
答案 0 :(得分:5)
问题出在您的Response类中:
validates_presence_of :user_id, :content
此验证需要user_id
的存在,这意味着必须在Response之前创建用户。为了使它工作,你可以尝试几件事:
将validates_presence_of :user_id
更改为validates_presence_of :user
,以使其验证User
对象而非用户ID。
使用inverse_of
选项。请参阅Rails API doc。
更新了代码。
<强> user.rb 强>
class User < ActiveRecord::Base
attr_accessible :responses_attributes
has_many :responses, :dependent => :destroy, :inverse_of => :user
accepts_nested_attributes_for :responses
# ...
end
<强> response.rb 强>
class Response < ActiveRecord::Base
belongs_to :user, :inverse_of => :responses
validates_presence_of :user, :content
end
答案 1 :(得分:1)
回答RoR v3:
问题是User
模型中的以下行:
attr_accessor :responses_attributes
将其替换为:
attr_accessible :responses_attributes
问题Difference between attr_accessor and attr_accessible
的答案应该有助于您理解两者之间的区别。
此外,您的验证validates :responses, presence: true
需要更新才能使用validates_associated
:
validates_associated :responses, presence: true
回答RoR v4:
我没有注意到使用强参数更早,为此道歉。一些更改应该可以解决您的问题:
attr_accessor :responses_attributes
型号中删除User
。validates :responses, presence: true
替换为validates_associated :responses, presence: true
responses
属性。如下所示:
class User < ActiveRecord::Base
# attr_accessor :responses_attributes # Remove this line
has_many :responses, :dependent => :destroy
accepts_nested_attributes_for :responses#, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
...
validates_associated :responses, presence: true # Update here
end
#Users Controller
class UsersController < ApplicationController
...
private
def user_params
params.require(:user).permit(:username, :email, :responses_attributes[:content])
end
end
答案 2 :(得分:0)
您的代码看起来几乎正确:
<强> user.rb 强>
class User < ActiveRecord::Base
has_many :responses, :dependent => :destroy
accepts_nested_attributes_for :responses
before_save { self.email = email.downcase }
validates :username, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX } ,
uniqueness: {case_sensitive: false};
end
<强> users_controller.rb 强>
private
def user_params
params.require(:user).permit(:username, :email, responses_attributes: [:content])
end