Sjo*_*ost 19 validation activerecord ruby-on-rails
鉴于一个模型:
class Person
validates_lenght_of :name, :maximum => 50
end
Run Code Online (Sandbox Code Playgroud)
我有一些显示倒计时的视图代码并强制执行此最大值.但是我将数字50硬编码到该视图代码中.有没有办法从模型中提取这个数字?
就像是:
Person.maximum_length_of_name
Run Code Online (Sandbox Code Playgroud)
我试过这个:
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}>]
Run Code Online (Sandbox Code Playgroud)
信息在那里,但我不知道如何提取它:
Vas*_*ich 16
使用validators_on方法
irb(main):028:0> p Person.validators_on(:name)[0].options[:maximum]
50
=> 50
Run Code Online (Sandbox Code Playgroud)
正如@Max Williams所说,它仅适用于Rails 3
Mat*_*ana 12
@nash答案的问题是验证器不拥有某个订单.我想出了如何用更多的代码做同样的事情,但是在某种更安全的模式下(因为你可以在以后添加更多的验证器并打破你获得它的顺序):
(Person.validators_on(:name).select { |v| v.class == ActiveModel::Validations::LengthValidator }).first.options[:maximum]
Run Code Online (Sandbox Code Playgroud)
我认为它也适用于Rails 3.
[编辑2017-01-17] Carefull我的答案是旧的(2012年),适用于Rails 3.它可能无法工作/适用于较新的Rails版本.
只是为了带来更多DRY精神,你可以创建一个泛型类方法来获得任何属性的最大"length_validator"值,如下所示:
在lib目录中创建一个模块并使其扩展ActiveSupport :: Concern:
module ActiveRecord::CustomMethods
extend ActiveSupport::Concern
end
# include the extension
ActiveRecord::Base.send(:include, ActiveRecord::CustomMethods)
Run Code Online (Sandbox Code Playgroud)
在其中添加"module ClassMethods"并创建"get_maximum"方法:
module ActiveRecord::CustomMethods
extend ActiveSupport::Concern
module ClassMethods
def get_maximum(attribute)
validators_on(attribute).select{|v| v.class == ActiveModel::Validations::LengthValidator}.first.options[:maximum]
end
end
end
Run Code Online (Sandbox Code Playgroud)
编辑1:配置
您还必须在其中一个初始化程序中添加require.
例如,这是我的配置:
config.autoload_paths +=
%W(#{config.root}/lib/modules)
注意:这不是必需的,但如果你想在你的应用程序之间共享一些自定义类和模块,那么这是最佳实践.require "active_record/extensions"
这应该做到!重新启动服务器,然后......
结束编辑1
然后你应该可以做这样的事情:
<%= form_for @comment do |f| %>
<%= f.text_area(:body, :maxlength => f.object.class.get_maximum(:body)) #Or just use Comment.get_maximum(:body) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
我希望它会帮助别人!:)当然,你可以按照你想要的方式自定义方法,并添加选项并做一些奇特的东西.;-)
更简洁:
Person.validators_on(:name).detect { |v| v.is_a?(ActiveModel::Validations::LengthValidator) }.options[:maximum]
Run Code Online (Sandbox Code Playgroud)
使用detect{}
替代select{}.first
和is_a?
取代class ==
.
这也适用于Rails 4.1.