[英]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.