web-dev-qa-db-ja.com

Railsデータベースなしのモデル

ActiveRecord検証付きのRails(2.1および2.2)モデルを作成しますが、データベーステーブルは使用しません。最も広く使用されているアプローチは何ですか?これを提供すると主張するプラグインがいくつか見つかりましたコミュニティが推奨することは何ですか?現在、私は このブログ投稿 に基づいた独自のソリューションを考えています。

64
FlipFlop

あなたがリンクしているブログ投稿が最善の方法だと思います。コードを汚染しないように、スタブアウトメソッドをモジュールに移動することをお勧めします。

8
Honza

Rails 3: http://railscasts.com/episodes/219-active-model でこれを行うより良い方法があります。

67
d135-1r43

これは私が過去に使用したアプローチです:

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>>
43
John Topley

簡単な方法があります:

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

http://api.rubyonrails.org/classes/ActiveModel/Model.html

19
hlcs

「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クラスだけが必要な場合は、このソリューションの方が良いかもしれません;)

8
tpinto

完全を期すために:

Rails(V5)には、含めることができる便利なモジュールがあります。

include ActiveModel::Model

これにより、ハッシュを使用して初期化することができ、とりわけ検証を使用できます。

完全なドキュメントは here です。

5
xmjw

Ryan Batesが作成した非アクティブレコードモデルについて screencast があります。開始するのに適した場所です。

念のため、まだ見ていません。

4
Laurent Farcy

John Topleyの提案に従って、これを処理するためのクイックMixinを構築しました。

http://github.com/willrjmarshall/Tableless

3
Will Marshall

クラスを抽象としてマークするのはどうですか?

class Car < ActiveRecord::Base
  self.abstract = true
end

これにより、Rails Carクラスに対応するテーブルがないことがわかります。

[編集]

次のような操作が必要な場合、これは実際には役立ちません。

my_car = Car.new
2
Mike Breen

誰でもこれまでにActiveRecord::ValidationsおよびActiveRecord::Validations::ClassMethods非アクティブレコードクラスで、バリデータを設定しようとするとどうなるかを確認します。

検証フレームワークとActiveRecord自体の間には多くの依存関係があると確信しています。ただし、AR検証フレームワークから独自の検証フレームワークをフォークすることにより、これらの依存関係を取り除くことに成功する場合があります。

ただのアイデア。

更新:おっと、これは多かれ少なかれあなたの質問にリンクされた投稿で提案されたものです。邪魔してごめんなさい。

1
Laurent Farcy

Tiago Pintoが言ったように、モデルにActiveRecord :: Baseを継承させないでください。これは、通常のRuby app/models /ディレクトリ内のファイルに貼り付けるクラスです。モデルにテーブルがなく、データベースまたはActiveRecordを使用していない場合アプリ内ですべて、environment.rbファイルを変更して次の行を含めるようにしてください。

config.frameworks -= [:active_record]

これはRails::Initializer.run do |config|ブロック内にある必要があります。

0
Sarah Vessels

PassiveRecord プラグインをチェックアウトする必要があります。非データベースモデル用のActiveRecordのようなインターフェイスを提供します。それはシンプルで、ActiveRecordと戦うよりも手間がかかりません。

PassiveRecordを Validatable gemと組み合わせて使用​​して、OPの望ましい動作を取得しています。

0
Tate Johnson