簡體   English   中英

沒有數據庫的Rails模型

[英]Rails model without database

我想創建一個帶有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

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

只需創建一個以“.rb”結尾的新文件,遵循您習慣使用的約定(文件名和類名稱的單數,文件名的下划線,類名稱的駝峰案例)。 這里的關鍵是不從ActiveRecord繼承您的模型(因為它是為您提供數據庫功能的AR)。 例如:對於汽車的新模型,在模型/目錄和模型內創建一個名為“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的功能但數據庫上沒有表格,我會告訴您。 如果你只是想要一個普通的Ruby類,也許你會發現這個解決方案更好;)

我認為您鏈接的博客文章是最好的方式。 我只建議將已刪除的方法移動到一個模塊中,以免污染您的代碼。

為了完整起見:

Rails現在(在V5)有一個方便的模塊,你可以包括:

include ActiveModel::Model

這允許您使用哈希初始化,並使用其他方面的驗證。

完整的文檔在這里

有一個關於非活動記錄模型的截屏視頻 ,由Ryan Bates編寫。 一個好的起點。

以防您沒有看過它。

根據John Topley的建議,我已經建立了一個快速的Mixin來處理這個問題。

http://github.com/willrjmarshall/Tableless

把這個類標記為抽象怎么樣?

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

這將告訴rails,Car類沒有相應的表。

[編輯]

如果您需要執行以下操作,這對您不會有任何幫助:

my_car = Car.new

使用Validatable gem。 如你所說,有基於AR的解決方案,但它們往往是脆弱的。

http://validatable.rubyforge.org/

有人試過在非Active Record類中包含ActiveRecord::ValidationsActiveRecord::Validations::ClassMethods ,看看嘗試設置驗證器時會發生什么?

我確信驗證框架和ActiveRecord本身之間存在大量依賴關系。 但是,您可以通過從AR驗證框架中分配自己的驗證框架來成功擺脫這些依賴關系。

只是一個想法。

更新 :oopps,這或多或少與您的問題鏈接的帖子中的建議。 對不起,打擾了。

你應該檢查PassiveRecord插件。 它為非數據庫模型提供了類似ActiveRecord的接口。 它比ActiveRecord更簡單,更輕松。

我們將PassiveRecord與Validatable gem結合使用以獲得OP所需的行為。

就像Tiago Pinto說的那樣,只是沒有你的模型繼承自ActiveRecord :: Base。 它只是一個常規的Ruby類,您可以將其粘貼到app / models /目錄中的文件中。 如果您的應用中沒有任何模型具有表,並且您根本沒有使用數據庫或ActiveRecord,請務必修改environment.rb文件以使其具有以下行:

config.frameworks -= [:active_record]

這應該在Rails::Initializer.run do |config| 塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM