ActiveRecord検証付きのRails(2.1および2.2)モデルを作成しますが、データベーステーブルは使用しません。最も広く使用されているアプローチは何ですか?これを提供すると主張するプラグインがいくつか見つかりましたコミュニティが推奨することは何ですか?現在、私は このブログ投稿 に基づいた独自のソリューションを考えています。
あなたがリンクしているブログ投稿が最善の方法だと思います。コードを汚染しないように、スタブアウトメソッドをモジュールに移動することをお勧めします。
Rails 3: http://railscasts.com/episodes/219-active-model でこれを行うより良い方法があります。
これは私が過去に使用したアプローチです:
app/models/tableless.rb
class Tableless < ActiveRecord::Base
def self.columns
@columns ||= [];
end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
sql_type.to_s, null)
end
# Override the save method to prevent exceptions.
def save(validate = true)
validate ? valid? : true
end
end
app/models/foo.rb
class Foo < Tableless
column :bar, :string
validates_presence_of :bar
end
スクリプト/コンソール
Loading development environment (Rails 2.2.2)
>> foo = Foo.new
=> #<Foo bar: nil>
>> foo.valid?
=> false
>> foo.errors
=> #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can't be blank"]}, @base=#<Foo bar: nil>>
簡単な方法があります:
class Model
include ActiveModel::Model
attr_accessor :var
validates :var, presence: true
end
ActiveModel::Model
コード:
module ActiveModel
module Model
def self.included(base)
base.class_eval do
extend ActiveModel::Naming
extend ActiveModel::Translation
include ActiveModel::Validations
include ActiveModel::Conversion
end
end
def initialize(params={})
params.each do |attr, value|
self.public_send("#{attr}=", value)
end if params
end
def persisted?
false
end
end
end
「models /」ディレクトリで、使用している規則(ファイル名とクラス名の単数形、ファイル名の下線付き、クラス名のキャメルケース)に従って「.rb」で終わる新しいファイルを作成するだけです。ここで重要なのは、ActiveRecordからモデルを継承しないことです(データベース機能を提供するのはARであるため)。例:車の新しいモデルの場合、models /ディレクトリおよびモデル内に「car.rb」というファイルを作成します。
class Car
# here goes all your model's stuff
end
編集:ところで、クラスの属性が必要な場合は、ここでRubyで使用するすべてのものを使用できます。「attr_accessor」を使用して数行を追加するだけです:
class Car
attr_accessor :wheels # this will create for you the reader and writer for this attribute
attr_accessor :doors # ya, this will do the same
# here goes all your model's stuff
end
編集#2:Mikeのコメントを読んだ後、ActiveRecordのすべての機能が必要で、データベースにテーブルが必要ない場合は、Mikeのやり方をお勧めします。通常のRubyクラスだけが必要な場合は、このソリューションの方が良いかもしれません;)
完全を期すために:
Rails(V5)には、含めることができる便利なモジュールがあります。
include ActiveModel::Model
これにより、ハッシュを使用して初期化することができ、とりわけ検証を使用できます。
完全なドキュメントは here です。
Ryan Batesが作成した非アクティブレコードモデルについて screencast があります。開始するのに適した場所です。
念のため、まだ見ていません。
John Topleyの提案に従って、これを処理するためのクイックMixinを構築しました。
クラスを抽象としてマークするのはどうですか?
class Car < ActiveRecord::Base
self.abstract = true
end
これにより、Rails Carクラスに対応するテーブルがないことがわかります。
[編集]
次のような操作が必要な場合、これは実際には役立ちません。
my_car = Car.new
誰でもこれまでにActiveRecord::Validations
およびActiveRecord::Validations::ClassMethods
非アクティブレコードクラスで、バリデータを設定しようとするとどうなるかを確認します。
検証フレームワークとActiveRecord自体の間には多くの依存関係があると確信しています。ただし、AR検証フレームワークから独自の検証フレームワークをフォークすることにより、これらの依存関係を取り除くことに成功する場合があります。
ただのアイデア。
更新:おっと、これは多かれ少なかれあなたの質問にリンクされた投稿で提案されたものです。邪魔してごめんなさい。
Tiago Pintoが言ったように、モデルにActiveRecord :: Baseを継承させないでください。これは、通常のRuby app/models /ディレクトリ内のファイルに貼り付けるクラスです。モデルにテーブルがなく、データベースまたはActiveRecordを使用していない場合アプリ内ですべて、environment.rbファイルを変更して次の行を含めるようにしてください。
config.frameworks -= [:active_record]
これはRails::Initializer.run do |config|
ブロック内にある必要があります。
PassiveRecord プラグインをチェックアウトする必要があります。非データベースモデル用のActiveRecordのようなインターフェイスを提供します。それはシンプルで、ActiveRecordと戦うよりも手間がかかりません。
PassiveRecordを Validatable gemと組み合わせて使用して、OPの望ましい動作を取得しています。