23

これは少し前に出てきました ( db に対応する列のない Rails モデル属性) が、言及されている Rails プラグインは維持されていないようです ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table )。ActiveRecord でこれをそのまま行う方法はありませんか?

そうでない場合、ActiveRecord を使用せずに ActiveRecord 検証ルールを取得する方法はありますか?

もちろん、ActiveRecord はテーブルが存在することを望んでいます。

4

7 に答える 7

39

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

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>>
于 2009-06-02T10:10:08.297 に答える
17

検証は、ActiveRecord内の単なるモジュールです。それらを非ActiveRecordモデルに混ぜてみましたか?

class MyModel
  include ActiveRecord::Validations

  # ...
end
于 2009-06-02T02:56:42.503 に答える
9

これは、「テーブルのないレール 3.1 モデル」を検索したときの Google での最初の結果の 1 つであるため、より多くの回答が得られると思います。

ActiveRecord::Base を使用せずに同じことを実装し、ActiveRecord::Validations を含めました。

主な目標は、すべてを formtastic で機能させることでした。以下に、どこにも保存されないが、誰もが知っていて愛用している検証を使用して検証できるサンプル支払いを含めました。

class Payment
  include ActiveModel::Validations
  attr_accessor :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state, :zip_code, :home_telephone, :email, :new_record

  validates_presence_of :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state

  def initialize(options = {})
    if options.blank?
      new_record = true
    else
      new_record = false
    end
    options.each do |key, value|
      method_object = self.method((key + "=").to_sym)
      method_object.call(value)
    end
  end

  def new_record?
    return new_record
  end

  def to_key
  end

  def persisted?
    return false
  end
end

今日これを理解しようと数時間を費やしたので、これが誰かの助けになることを願っています。

于 2011-11-29T23:37:30.537 に答える
8

更新: Rails 3の場合、これは非常に簡単に実行できます。ActiveModelRails 3+では、新しいモジュールとそのサブモジュールを使用できます。これは今動作するはずです:

class Tableless
  include ActiveModel::Validations

  attr_accessor :name

  validates_presence_of :name
end

詳細については、このトピックに関するRailscast(またはAsciiCastsでそれについて読む)、およびYehudaKatzによるこのブログ投稿を確認できます。

古い答えは次のとおりです。

前のコメントでJohnTopleyによって提案されたソリューションにこれを追加する必要があるかもしれません:

class Tableless

  class << self
    def table_name
      self.name.tableize
    end
  end

end

class Foo < Tableless; end
Foo.table_name # will return "foos"

これにより、必要に応じて「偽の」テーブル名が提供されます。この方法がないFoo::table_nameと、「テーブルレス」と評価されます。

于 2009-12-17T15:55:39.810 に答える
2

受け入れられた答えへの単なる追加:

サブクラスが親列を継承するようにするには、次のようにします。

class FakeAR < ActiveRecord::Base
  def self.inherited(subclass)
    subclass.instance_variable_set("@columns", columns)
    super
  end

  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

  # Overrides save to prevent exceptions.
  def save(validate = true)
    validate ? valid? : true
  end
end
于 2013-08-14T17:02:33.810 に答える
1

これは、開始属性と終了属性を持つネストされた期間オブジェクトを持つ条件と呼ばれるオブジェクトを表示する検索フォームです。

コントローラのアクションは非常にシンプルですが、フォーム上のネストされたオブジェクトから値をロードし、必要に応じてエラーメッセージを表示して同じ値を再レンダリングします。

Rails3.1で動作します。

モデル:

class Criteria < ActiveRecord::Base
  class << self

    def column_defaults
      {}
    end

    def column_names
      []
    end
  end # of class methods

  attr_reader :period

  def initialize values
    values ||= {}
    @period = Period.new values[:period] || {}
    super values
  end

  def period_attributes
    @period
  end
  def period_attributes= new_values
    @period.attributes = new_values
  end
end

コントローラ内:

def search
  @criteria = Criteria.new params[:criteria]
end

ヘルパーで:

def criteria_index_path ct, options = {}
  url_for :action => :search
end

ビューで:

<%= form_for @criteria do |form| %>
  <%= form.fields_for :period do |prf| %>
    <%= prf.text_field :beginning_as_text %>
    <%= prf.text_field :end_as_text %>
  <% end %>
  <%= form.submit "Search" %>
<% end %>

HTMLを生成します:

<form action="/admin/search" id="new_criteria" method="post">
  <input id="criteria_period_attributes_beginning_as_text" name="criteria[period_attributes][beginning_as_text]" type="text"> 
  <input id="criteria_period_attributes_end_as_text" name="criteria[period_attributes][end_as_text]" type="text">

:ヘルパーによって提供されるアクション属性と、コントローラーがすべての値を一度にロードするのを非常に簡単にするネストされた属性の命名形式

于 2011-10-25T20:53:15.650 に答える
1

activerecord-tableless gemがあります。テーブルレス ActiveRecord モデルを作成するための gem であるため、検証、関連付け、型がサポートされています。Active Record 2.3、3.0、3.2に対応

Rails 3.x で推奨される方法 (ActiveModel を使用) では、関連付けも型もサポートされていません。

于 2013-02-20T14:12:16.240 に答える