2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails3.2でバリデーションを動的に追加するとうまく動かない

Last updated at Posted at 2014-01-24

Railsのフォームでは以下のような記述で簡単にバリデーションを追加することができます。

class ModelName < ActiveRecord::Base
  attr_accessible :attr
  validates :attr, presence: true
end

このバリデーションの部分はActiveModel::Validationsとしてモジュールになっているので、永続化機構を持たない(DBにテーブルがない)場合でもバリデーションの機能のみ利用することができます。
僕はこれを利用してフォームとして利用することがよくあります。

class SomeForm
  extend ActiveModel::Naming
  include ActiveModel::Validations
  attr_accessor :attr
  validates :attr, presence: true
end

大抵の場合はこれでまったく問題ないのですが、フォームの項目が動的に変わる場合、バリデーションルールも動的に追加したいのですがそうするとうまく動かないという現象に遭遇しました。
(稀なケースだと思いますが、例えば管理画面で設問を設定する場合など。)

class DynamicForm
  extend ActiveModel::Naming
  include ActiveModel::Validations

  def initialize(attrs = [ :attr1, attr2 ])
    @attrs = {}

    attrs.each do |attr|
      instance_eval <<-DEFINE_GETTER_AND_SETTER_AND_PRESENCE_VALIDATOR
        class << self
          validates :#{attr}, presence: true # これが動かない!

          def #{attr}
            @attr[#{attr}]
          end

          def #{attr}=(value)
            @attr[#{attr}] = value
          end
        end
      DEFINE_GETTER_AND_SETTER_AND_PRESENCE_VALIDATOR
    end
  end
end

まだ解決できていないのですが備忘録として書きました。
余裕で来たらソースコード追ってみます。


Rails4ではActiveModel::Modelを利用することができるようになったのでこれ使えば大丈夫なのかなぁ…

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?