这是事情。让我们说我有一个用户模型,订单模型和地址模型。
class User < ActiveRecord::Base
belongs_to :address, :foreign_key => :address_id, :class_name => "Address"
end
class Order < ActiveRecord::Base
belongs_to :address, :foreign_key => :address_id, :class_name => "Address"
end
class Address < ActiveRecord::Base
attr_accessible :email, :address
end
现在,在用户模型上,我想验证地址模型的电子邮件字段。
但是在Order模型上,我想验证地址模型的地址字段。
我试过这个:
class User < ActiveRecord::Base
belongs_to :address, :foreign_key => :address_id, :class_name => "Address"
validate :address_fields
def address_fields
self.address.errors.add 'email' unless self.address.email.present?
end
end
它在控制台中可以正常工作,但是Simple Form没有看到错误,也没有显示错误。
有任何想法正确地做到了吗?
答案 0 :(得分:1)
听起来你很亲密,但有一些细微之处取决于你想要做什么。
通常,Rails设置为以模型为中心的验证 - 也就是说,模型有效或不有效。 Rails希望您的验证出现在您正在验证的模型上,并提供validates_associated
validator来帮助您。这是一个示例,我在Address
上添加了一些规则,并告诉User
和Order
模型在保存时验证它们。
class User < ActiveRecord::Base
belongs_to :address
validates_associated :address
end
class Order < ActiveRecord::Base
belongs_to :address
validates_associated :address
end
class Address < ActiveRecord::Base
has_many :users
has_many :orders
attr_accessible :email, :address
# This isn't a good regex for validating email addresses, it's just an example
validates :email, format: { with: /^[A-z0-9]+@[A-z0-9.]+.[A-z]$/ }
validates :address, presence: true
end
您还可以使用验证时的:if
和:unless
选项conditional validations。例如,如果您想要Address
上的电话号码,只要它是美国Address
,您可以使用此号码:
validates :phone_number, presence: true, if: :us_address?
def us_address?
country == "United States"
end
如果您的Address
可以拥有多个用户(例如,多个人可能订购公司地址)并且可以拥有多个订单(因为客户可以订购多次),则很难编写条件验证符合您要求的规则的Address
模型。我想到了几种选择:
User
模型上。你不能给建筑物发电子邮件,所以它更有意义。如果您想要快照用户的电子邮件地址以便重现发票,那么可能会在confirmation_sent_to_email
上添加Order
字段。 OrderAddress
和UserAddress
。它们可以具有不同的验证规则,并且在您的应用程序中将更清楚您正在处理的类型。您仍然可以拥有仅包含地址详细信息的Address
模型,并根据需要将其与OrderAddress
和UserAddress
模型相关联。答案 1 :(得分:1)
一个简单的答案。
向用户添加错误而不是user.address。
class User < ActiveRecord::Base
def address_fields
self.errors.add 'email' unless self.address.email.present?
end
end
然后,您可以在简单用户表单上看到错误。
或者您可以像这样更新用户表单,以处理user.errors和user.address.errors:
<% if @user.errors.any? || @user.address.errors.any?%>
<div id="error_explanation">
<h2><%= pluralize(@user.errors.count + @user.address.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<ul>
<% @user.address.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>