Ruby on rails Rails:验证关联上的字段
事情是这样的。假设我有一个用户模型、订单模型和地址模型Ruby on rails Rails:验证关联上的字段,ruby-on-rails,ruby-on-rails-3,validation,simple-form,Ruby On Rails,Ruby On Rails 3,Validation,Simple Form,事情是这样的。假设我有一个用户模型、订单模型和地址模型 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, :c
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
class用户:address\u id,:class\u name=>“address”
结束
类顺序:address\u id,:class\u name=>“address”
结束
类地址
现在在用户模型上,我只想验证地址模型的email字段
但是在订单模型上,我只想验证地址模型的地址字段
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
我试过这个:
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
class用户:address\u id,:class\u name=>“address”
验证:地址字段
def地址_字段
self.address.errors.添加“电子邮件”,除非self.address.email.present?
结束
结束
它确实在控制台中工作,但Simple Form没有看到错误,也没有显示错误
有什么好办法吗?听起来你很接近了,但根据你想做什么,有一些微妙之处 通常,Rails是为以模型为中心的验证而设置的,也就是说,模型要么有效,要么无效。Rails希望您的验证出现在正在验证的模型上,并提供了帮助。下面是一个例子,我在
地址
上添加了一些规则,并告诉用户
和订单
模型在保存时验证它们
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
如果您的地址
可以有多个用户(例如,一个公司地址可能有多个人下单)并且可以有多个订单(因为客户可以多次下单),则很难在地址
模型上编写符合您要求的规则的条件验证。脑海中浮现出两个备选方案:
- 将电子邮件存储在
型号上。你不能给建筑物发电子邮件,所以在那里更有意义。如果您希望快照用户的电子邮件地址,以便可以复制发票,那么可以在您的用户
上包含一个订单
字段李>确认发送到\u电子邮件
- 有两种不同的型号,一种是
,另一种是OrderAddress
。它们可以有不同的验证规则,并且在应用程序中处理哪种类型的验证规则会更清晰。您仍然可以拥有一个只保存地址详细信息的UserAddress
模型,并根据需要将其与地址
和订单地址
模型相关联用户地址
一个简单的答案
将错误添加到user而不是user.address
class User < ActiveRecord::Base
def address_fields
self.errors.add 'email' unless self.address.email.present?
end
end
class用户
然后,您可以在简单的用户表单上看到错误
或者,您可以像这样更新用户表单,以处理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 %>
禁止保存此用户:
问题在于,它将在用户字段而不是电子邮件字段旁边显示错误。。。否?这取决于您如何处理表单上的错误。在用户窗体上,通常处理诸如
之类的错误。如果要显示更多错误,可以更新到
。查看我的更新。谢谢你的回答。你的两个建议似乎有点混乱,但给了我一个想法。地址模型有两个子类,OrderAddress和UserAddress。唯一的区别是验证。这样行吗?你可以这样做——Rails希望你使用——但我还是倾向于选择1。使用STI添加DB级别的约束会更难,查看数据并确定其是否正常也会更难。