【发布时间】:2015-09-09 22:03:21
【问题描述】:
Update2:我已经清理了代码,似乎解决了一些问题。我已将新代码作为新问题 here 发布。
更新:组织和用户是一对多的关系。我的问题涉及需要组织和用户的联合注册表单。在 maxcal 对原帖的帮助之后,我为我的嵌套表单(“组织有很多用户”)编写了一个新的 create 方法,如下所示。我还在create 方法中添加了begin...rescue...end。现在的情况/问题:
- 提交的所有有效信息都可以正常工作。
- 提交的组织信息无效(无论用户是否无效),它会按照我们的意愿呈现带有错误消息的页面,但它只显示组织详细信息的错误。此外,对于用户详细信息,它随后清空了所有不应该的字段。
- 只为用户提交了无效信息,它再次呈现表单但没有任何错误消息,并且用户的所有字段都已清空。
有人知道代码有什么问题吗?嵌套用户的问题似乎比组织(父级)更多。此外,根据日志,users_attributes.empty? 不起作用,因为提交的空表单仍然包含此类属性:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"***", "organization"=>{"name"=>"", "bag"=>"", "users_attributes"=>{"0"=>{"email"=>"", "username"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "usertype"=>"2", "admin"=>"true"}}}, "commit"=>"Register"}
.
def create
@organization = Organization.new(new_params.except(:users_attributes))
begin
if users_attributes.empty?
@organisation.errors.add(:users, 'No user provided')
end
@organization.transaction do
@organization.save!
if users_attributes.any?
@organization.users.create!(users_attributes)
end
end
rescue ActiveRecord::RecordInvalid => invalid
if @organization.persisted?
if @organization.users.any?
@organization.users.each do |single_user|
single_user.send_activation_email
end
end
flash[:success] = "Confirmation email sent."
redirect_to root_url
else
@organization.users.build if @organization.users.blank?
render :new
end
end
end
private
# converts the hash of nested attributes hashes to an array
def users_attributes
new_params[:users_attributes].values
end
end
原问题:
我有两个关联的模型和一个带有验证的嵌套表单。不幸的是,它不起作用。 1) 在 播种 时,它会生成错误 Validation failed: Users organization can't be blank。我previously posted对此提出了一个问题,并过早地得出结论,它已经解决了。它没有。 2) 提交我的嵌套 注册表单 并正确填写所有字段,会产生 Flash 错误消息 The form contains 1 error. Users organization can't be blank。
我应该如何调整我的代码来解决这些问题?
模型文件:
#User model
belongs_to :organization, inverse_of: :users
validates_presence_of :organization_id, :unless => 'usertype == 1'
# Organization model
has_many :users, dependent: :destroy
accepts_nested_attributes_for :users, :reject_if => :all_blank, :allow_destroy => true
validate :check_user
private
def check_user
if users.empty?
errors.add(:base, 'User not present')
end
end
组织控制器方法
def new
@organization = Organization.new
@user = @organization.users.build
end
def create
@organization = Organization.new(new_params)
if @organization.save
@organization.users.each do |single_user|
single_user.send_activation_email # Method in user model file.
end
flash[:success] = "Confirmation email sent."
redirect_to root_url
else
@organization.users.build if @organization.users.blank?
render 'new'
end
end
def new_params
params.require(:organization).permit(:name, :bag,
users_attributes: [:email, :username, :usertype, :password, :password_confirmation])
end
形式:
<%= form_for @organization, url: organizations_path do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_field :name %>
<%= f.text_field :bag %>
<%= f.fields_for :users do |p| %>
<%= p.email_field :email %>
<%= p.text_field :username %>
<%= p.text_field :fullname %>
<%= p.password_field :password %>
<%= p.password_field :password_confirmation %>
<%= p.hidden_field :usertype, value: 2 %>
<% end %>
在我的种子文件中,我有:
Organization.create!(name: "Fictious business",
address: Faker::Address.street_address,
city: Faker::Address.city,
users_attributes: [email: "helpst@example.com",
username: "helpyzghtst",
usertype: 2,
password: "foobar",
password_confirmation: "foobar"])
提交注册表时的错误日志:
Started POST "/organizations"
Processing by OrganizationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0cR***Nnx4iReMiePg==", "organization"=>{"name"=>"test21", "bag"=>"tes21", "users_attributes"=>{"0"=>{"email"=>"test21@example.com", "username"=>"test21", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "usertype"=>"2"}}}, "commit"=>"Register"}
(0.2ms) BEGIN
User Exists (1.1ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('test21@example.com') LIMIT 1
(0.7ms) SELECT "users"."email" FROM "users" ORDER BY "users"."username" ASC
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE LOWER(users"."username") = LOWER('test21') LIMIT 1
Organization Exists (0.6ms) SELECT 1 AS one FROM "organizations" WHERE LOWER("organizations"."name") = LOWER('test21') LIMIT 1
Organization Exists (0.4ms) SELECT 1 AS one FROM "organizations" WHERE LOWER("organizations"."bag") = LOWER('tes21') LIMIT 1
(0.2ms) ROLLBACK
【问题讨论】:
-
尝试更改为
validates_presence_of :organization, :unless => 'usertype == 1'(删除_id)。不久前我遇到了类似的问题,此更改已解决 -
试过了,但不幸的是它产生了完全相同的错误。
-
毫米。我检查了我的代码,唯一的其他区别是 inverse_of 在组织模型上,而不是在用户模型上
-
对除非使用 lambda。
unless: -> { usertype == 1 } -
如果我将
:unless => 'usertype == 1'更改为:if=> 'usertype == 3'(永远不会),它会起作用。那是因为它不会进行任何验证,因为 usertype 永远不会是 3。但是显示validates_presence_of行的第二半工作正常,并且当 usertype 不是 1 时它会应用验证。所以unless: -> { usertype == 1 }仍然产生相同的错误.如果我在组织模型上应用inverse_of,则会收到错误InverseOfAssociationNotFoundError。但我也可以将inverse_of排除在我的模型之外;它似乎没有多大作用。
标签: ruby-on-rails ruby validation ruby-on-rails-4 nested-forms