I have a form that includes two models, one of which is nested in another. When on the development server I submit the form, the submission generates the flash error message:
The form contains 1 error:
* Members organization can't be blank
Each Member belongs to 1 Organization. Might the error have to do with that the organization isn't saved yet when it's trying to save the Member (for a new organization, it's supposed to simulateneously save the organization and member)? Should I add code that sets organization_id for the member (but I would expect @organization.members.build
to take care of that)? What am I doing wrong here?
The server log:
Processing by OrganizationsController#create as HTML
Parameters: {"utf8"=>"✓", "organization"=>{"org_name"=>"sadfsdaf", "phone"=>"sdfds", "members_attributes"=>{"0"=>{"username"=>"fsfdsfsad", "email"=>"sfdsdf@sfsdf.com", "fullname"=>"sdfds", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}}, "admin"=>"true", "commit"=>"Sign up"}
(0.5ms) begin transaction
Member Exists (0.4ms) SELECT 1 AS one FROM "members" WHERE LOWER("members"."email") = LOWER('sfdsdf@sfsdf.com') LIMIT 1
Member Exists (0.2ms) SELECT 1 AS one FROM "members" WHERE LOWER("members"."username") = LOWER('fsfdsfsad') LIMIT 1
Organization Exists (0.3ms) SELECT 1 AS one FROM "organizations" WHERE LOWER("organizations"."org_name") = LOWER('sadfsdaf') LIMIT 1
Organization Exists (0.2ms) SELECT 1 AS one FROM "organizations" WHERE LOWER("organizations"."phone") = LOWER('sdfds') LIMIT 1
(0.2ms) rollback transaction
Rendered shared/_error_messages.html.erb (1.9ms)
Organization model:
has_many :members, dependent: :destroy
accepts_nested_attributes_for :members, :reject_if => :all_blank, :allow_destroy => true
Member model:
belongs_to :organization
validates :organization_id, presence: true # There are other validations as well, but I don't think they matter for this question.
def send_activation_email
MemberMailer.account_activation(self).deliver_now
end
Organization controller:
def new
@organization = Organization.new
@member = @organization.members.build
end
def create
@organization = Organization.new(organizationnew_params)
if @organization.save
@member.send_activation_email # Method in Member model file.
flash[:success] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
private
def organizationnew_params
params.require(:organization).permit(:org_name,
:phone,
member_attributes: [:email,
:username,
:admin,
:password,
:password_confirmation
])
end
New view:
<%= form_for(@organization) do |f| %>
<%= f.text_field :org_name, %>
<%= f.text_field :phone %>
<%= f.fields_for :members do |p| %>
<%= p.text_field :username %>
<%= p.email_field :email %>
<%= p.password_field :password %>
<%= p.password_field :password_confirmation %>
<%= hidden_field_tag :admin, true %>
<% end %>
<%= f.submit "Sign up", class: "formbutton btn btn-default" %>
<% end %>
答案 0 :(得分:1)
在允许的参数上,尝试将member_attributes
更改为members_attributes
。同样在创建操作上您指的是@member
,但尚未定义。
要进一步调试,请使用以下命令替换您的创建操作:
def create
return render text: organizationnew_params
end
这样,当您发送表格时,您将获得所有允许的参数,并检查它是否符合您的预期。
发送电子邮件替换
@member.send_activation_email
使用
@organization.members.each do |single_member|
single_member.send_activation_email
end
请使用此
def create
@organization = Organization.new(organizationnew_params)
if @organization.save
@organization.members.each do |single_member|
single_member.send_activation_email
end
flash[:success] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
private
def organizationnew_params
params.require(:organization).permit(:org_name,
:phone,
members_attributes: [:id,:email,
:username,
:admin,
:password,
:password_confirmation
])
end
使用members
(oraganization
)创建OraganizationsController
时,您无需验证organization_id
,因为它将在{organization
的同一时间创建1}}。很遗憾,在向organization_id
添加新的member
时,您需要验证organization
。所以我们可以做的是为验证添加一个条件:
#member.rb
attr_accessor :require_organization_id
belongs_to :organization
validates :organization_id, presence: true, if: :require_organization_id
member = Member.new(name: "Some Name")
member.valid? #true
member.require_organization_id = true
member.valid? #false
member.organization = Organization.first
member.valid? #true
答案 1 :(得分:0)
如果在成员模型中设置验证,即
validates :organization_id, presence: true
然后它会在member_id的成员参数中查找并不存在于memeber的参数中
"members_attributes"=>{"0"=>{"email"=>"sfsa@sfsd.com", "username"=>"fsfdsfsad", "fullname"=>"sdfds", "password"=>"foobar", "password_confirmation"=>"foobar"}}
这就是为什么它显示验证错误所以删除这一行
validates :organization_id, presence: true
来自您的会员模型
同样对于@member问题,你需要这样做
@organization.memebers.each do |member|
member.send_activation_email
end