Ruby on rails 如何获得ActiveRecord验证中配置的最大长度?
给定一个模型:Ruby on rails 如何获得ActiveRecord验证中配置的最大长度?,ruby-on-rails,validation,activerecord,Ruby On Rails,Validation,Activerecord,给定一个模型: class Person validates_lenght_of :name, :maximum => 50 end 我有一些显示倒计时的视图代码,并强制执行此最大值。然而,我把数字50硬编码到了视图代码中。有没有办法从模型中提取这个数字 比如: Person.maximum_length_of_name 我试过这个: Person.validators_on(:name) => [#<ActiveRecord::Validations::Unique
class Person
validates_lenght_of :name, :maximum => 50
end
我有一些显示倒计时的视图代码,并强制执行此最大值。然而,我把数字50硬编码到了视图代码中。有没有办法从模型中提取这个数字
比如:
Person.maximum_length_of_name
我试过这个:
Person.validators_on(:name)
=> [#<ActiveRecord::Validations::UniquenessValidator:0x000001067a9840 @attributes=[:name], @options={:case_sensitive=>true}, @klass=Trigger(id: integer, name: string, created_at: datetime, updated_at: datetime, user_id: integer, slug: string, last_update_by: integer)>, #<ActiveModel::Validations::PresenceValidator:0x000001067a6c30 @attributes=[:name], @options={}>, #<ActiveModel::Validations::LengthValidator:0x000001067a3f08 @attributes=[:name], @options={:tokenizer=>#<Proc:0x00000101343f08@/Users/sjors/.rvm/gems/ruby-1.9.2-p0/gems/activemodel-3.0.6/lib/active_model/validations/length.rb:9 (lambda)>, :maximum=>50}>]
Person.validators\u on(:name)
=>[#true},@klass=Trigger(id:integer,name:string,创建时间:datetime,更新时间:datetime,用户id:integer,slug:string,上次更新时间:integer)>,#,##,:max=>50}>]
信息在那里,但我不知道如何提取它:使用方法
正如@Max Williams所提到的,它只在Rails 3上工作,如果您在Rails 2中,这并不容易。我记得我以前试过这个,没走多远。您可以查看验证对象,但它们没有列出它们用于哪个字段,这对我来说非常奇怪。人们已经为此做了插件(即检查或反思AR对象的验证),例如,@nash answer的问题是,验证程序不拥有特定的顺序。我发现了如何用更多的代码来做同样的事情,但是使用了某种更安全的模式(因为你可以在以后添加更多的验证器,打破你得到它的顺序):
我认为它也只适用于Rails 3。[Edit 2017-01-17]小心地我的答案是旧的(2012年),适用于Rails 3。对于较新的Rails版本,它可能不起作用/不理想
只需稍微简化一下,您可以创建一个泛型类方法来获取任何属性上的最大“length\u validator”值,如下所示: 在lib目录中创建模块并使其扩展: 在其中添加“模块类方法”,并创建“获取最大值”方法: 编辑1:配置 您还必须在其中一个初始值设定项中添加require 例如,以下是我的配置:
config.autoload\u path+=
%W(#{config.root}/lib/modules)
注意:这不是必需的,但如果您想将在应用程序之间共享的一些自定义类和模块放在那里,则是最佳做法require“active\u record/extensions”
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.get_maximum(:body)) #Or just use Comment.get_maximum(:body) %>
<% end %>
f、 object.class.get_max(:body))35;或只使用Comment.get_max(:body)%>
我希望它能帮助别人!:)当然,您可以按照自己的方式自定义该方法,添加选项,并执行一些奇特的操作。;-) Kulgar的答案是好的,可能是理想的。对于Rails 4,这里有一个更简单的方法可以做到这一点,它不需要修改任何配置,缺点是您必须为每个想要使用它的模型添加一个include行 模型/关注点/内省.rb:
module Introspection
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def max_length(property)
Resource.validators_on(property.to_sym).
select{ |v| v.kind_of?(ActiveModel::Validations::LengthValidator) }.
first.options[:maximum]
end
end
end
然后在您的模型中:
class Comment < ActiveRecord::Base
include Introspection
..
end
class注释
然后你可以这样做:
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.max_length(:body)) %> # Or just use Comment.max_length(:body) %>
<% end %>
f、 object.class.max_length(:body))%>#或仅使用Comment.max_length(:body)%>
更简洁:
Person.validators_on(:name).detect{v | v.is_a?(ActiveModel::Validations::LengthValidator)}.options[:max]
使用检测{}
代替选择{}。首先
和是{u a?
代替类==
这也适用于Rails 4.1。比Kulgar的答案更具动态性的是使用以下内容:
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.max_length(:body)) %> # Or just use Comment.max_length(:body) %>
<% end %>
Person.validators\u on(属性)
.选择{| v | v.class==ActiveRecord::Validations::LengthValidator}
.选择{v | v.options[:maximum].present?}.first.options[:maximum]
这样您就可以按照您想要的方式订购模型中的验证器
将其用作Rails助手
然后,您可以使用以下代码编写帮助程序:
#返回模型给定属性的最大长度
def get_maxlength(型号、属性)
model.validators_on(属性)
.选择{| v | v.class==ActiveRecord::Validations::LengthValidator}
.选择{v | v.options[:maximum].present?}.first.options[:maximum]
结束
并像这样使用帮助器:
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.max_length(:body)) %> # Or just use Comment.max_length(:body) %>
<% end %>
=f.text_字段:name,maxlength:get_maxlength(f.object.class,:name)#或使用get_maxlength(Person,:name)
这是一个间接的答案,但也是一个替代解决方案,以防它对任何人都有用
备选方案1
班级人员
最大长度={
姓名:50,,
#电子邮件:30等。。。
}.别动
验证:名称,长度:{maximum:MAX_length.fetch(:name)}
结束
#视图文件中的使用示例
备选方案2
。。。或者,如果您喜欢单行程序,或者不使用散列常量
class Person
validates :name, length: { maximum: (MAX_NAME_LENGTH = 50) }
# validates :password, length: {
# minimum: (MIN_PASSWORD_LENGTH = 8),
# maximum: (MAX_PASSWORD_LENGTH = 70)
# }
# ... etc
end
# usage example in view file
<%= Person.MAX_NAME_LENGTH %>
班级人员
验证:名称,长度:{MAX:(MAX_name_length=50)}
#验证:密码,长度:{
#最小值:(最小密码长度=8),
#最大值:(最大密码长度=70)
# }
# ... 等
结束
#视图文件中的使用示例
我想这只是rails 3。这可能不是问题,Sjors没有指定:)谢谢,我确实使用Rails 3,但它对我不起作用。我将Person.validators的输出添加到我的原始帖子中。在您的案例中,它将是(:name)[2]上的Person.validators\u。选项[:最大值]
这是一个更好的答案。对于更多的“干法”,很容易将此方法添加为ActiveRecord通用方法。我在下面的回答中解释了如何操作。我将代码放在/lib中,设置config.autoload\u路径+=%W(#{config.root}/lib)
并重新启动了服务器,但仍然为#获得了未定义的方法“get\u max”。还有什么需要配置的吗?文件名限制?是的,我的错,我忘了告诉你必须在一个初始值设定项中要求它。。。我将
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.max_length(:body)) %> # Or just use Comment.max_length(:body) %>
<% end %>
class Person
MAX_LENGTHS = {
name: 50,
# email: 30, etc...
}.freeze
validates :name, length: { maximum: MAX_LENGTHS.fetch(:name) }
end
# usage example in view file
<%= Person.MAX_LENGTHS.fetch(:name) %>
class Person
validates :name, length: { maximum: (MAX_NAME_LENGTH = 50) }
# validates :password, length: {
# minimum: (MIN_PASSWORD_LENGTH = 8),
# maximum: (MAX_PASSWORD_LENGTH = 70)
# }
# ... etc
end
# usage example in view file
<%= Person.MAX_NAME_LENGTH %>