[英]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
只需創建一個以“.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類,也許你會發現這個解決方案更好;)
我認為您鏈接的博客文章是最好的方式。 我只建議將已刪除的方法移動到一個模塊中,以免污染您的代碼。
有一個關於非活動記錄模型的截屏視頻 ,由Ryan Bates編寫。 一個好的起點。
以防您沒有看過它。
根據John Topley的建議,我已經建立了一個快速的Mixin來處理這個問題。
把這個類標記為抽象怎么樣?
class Car < ActiveRecord::Base
self.abstract = true
end
這將告訴rails,Car類沒有相應的表。
[編輯]
如果您需要執行以下操作,這對您不會有任何幫助:
my_car = Car.new
使用Validatable gem。 如你所說,有基於AR的解決方案,但它們往往是脆弱的。
有人試過在非Active Record類中包含ActiveRecord::Validations
和ActiveRecord::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.