如何验证不对应于数据库列的参数?

How can I validate params that don't corrospond to a db column?

我有一个带有字符串属性 name 的模型 User。在我创建新 User 的表单上,很容易验证 name 属性:

models/user.rb

validates :name, presence: true, length: {maximum: 13}

users_controller.rb

private

def user_params
  params.require(:user).permit(:name, :words)
end

但是,我想验证 不是 属性或数据库列的参数。在我的表单上,我有一个文本框,将 params["words"] 作为字符串提交。我知道正在提交参数,因为我可以使用 binding.pry 与其交互。但是,如果我尝试以与 Name 相同的方式验证它,则什么也不会发生。表单提交时有或没有 words。如何验证不是属性的参数?

我的表格:

<%= form_for @user, :url => users_path do |f| %>
  <%= f.text_field :name %>
  <input id="words" name="words">
  <%= f.submit "Submit", class: "btn" %>
<% end %>

表单应提交 params['user']['words'] 而不是 params['words'],并且您的用户模型应具有 attr_accessor :words.

如果要执行包含 :words 的模型验证,则需要在 User.rb 文件中添加 :words 作为虚拟属性,以便模型可以访问给它。您只需将此行添加到 User.rb 文件即可:

attr_accessor :words

然后您的模型现在可以对其执行验证,例如:

validates_presence_of :words

您还需要确保 :words 参数属于 :user 并且作为 params["user"]["words"]

发送

编辑:

要让您的表单 post 嵌套在 :user 下的 :words 参数,请将您的表单输入更改为:

<input id="words" name="user[words]">

因为用户模型现在有虚拟属性 :words 你可以设置你的表单 rails 方式。

<%= f.text_field :words %>


attr_accessors 上的 APIDock 参考: http://apidock.com/ruby/Module/attr_accessor

虚拟属性参考: http://www.linuxtopia.org/online_books/programming_books/ruby_tutorial/Ruby_Classes_Objects_and_Variables_Virtual_Attributes.html

尝试将您的值放在 params[:user][:words] 而不是 params[:words] 中,并在您的模型中添加 attr_accessor :words

您可以将 words 属性添加到 User class。

class User < ActiveRecord::Base
  attr_accessor :words

  validates :words, presence: true, length: {maximum: 13}

  def initialize(arguments = {}, options = {})
    self.words = arguments.delete :words
    super
  end
end

但是,不推荐覆盖 ActiveRecord 初始化方法。似乎这种验证应该只发生在这个动作中。

正确的方法应该是使用表单对象。您可以在此处了解更多信息:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/