Rails模型没有数据库
我想用ActiveRecordvalidation创build一个Rails(2.1和2.2)模型,但没有数据库表。 什么是最广泛使用的方法? 我发现一些声称提供这种function的插件,但是其中许多插件似乎没有被广泛使用或维护。 社区推荐我做什么? 现在我倾向于基于这篇博客文章提出自己的解决scheme。
我认为你所链接的博文是最好的select。 我只会build议将残存的方法移动到不污染代码的模块中。
在Rails 3中有一个更好的方法: http : //railscasts.com/episodes/219-active-model
这是我过去使用的方法:
在应用程序/模型/ 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
在应用程序/模型/ 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
只需按照您习惯的惯例(在文件名和类名中单引号,在文件名中加上下划线,在名称中加上驼名)在“models /”目录下创build一个以“.rb”结尾的新文件。 这里的关键是不从ActiveRecordinheritance你的模型(因为它是AR给你的数据库function)。 例如:对于汽车的新模型,在模型/目录和模型中创build一个名为“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的function,但是没有数据库表格,我会告诉你。 如果你只想要一个普通的Ruby类,也许你会发现这个解决scheme更好;)
Ryan Bates制作了非活动logging模型的屏幕录像 。 一个好的地方,从开始。
以防万一你没有看到它。
按照约翰·托皮利的build议,我已经build立了一个快速的Mixin来处理这个问题。
把class级标记为抽象是什么?
class Car < ActiveRecord::Base self.abstract = true end
这会告诉Rails Car类没有相应的表。
[编辑]
这不会真的帮助你,如果你需要做的事情如:
my_car = Car.new
使用Validatablegem。 正如你所说,有基于AR的解决scheme,但它们往往是脆弱的。
任何人ActiveRecord::Validations::ClassMethods
在非Active Record类中包含ActiveRecord::Validations
和ActiveRecord::Validations::ClassMethods
,并且看看在设置validation器时会发生什么?
我确信validation框架和ActiveRecord本身之间有很多依赖关系。 但是,您可以通过从ARvalidation框架中派生出自己的validation框架来成功摆脱这些依赖关系。
只是一个想法。
更新 :oopps,这或多或less是什么build议在与您的问题链接的职位。 对不起,这个干扰。
为了完整:
Rails现在(在V5)有一个方便的模块,你可以包括:
include ActiveModel::Model
这允许您使用散列进行初始化,并使用validation等等。
完整的文档在这里 。
像Tiago Pinto说的那样,只是没有从ActiveRecord :: Baseinheritance你的模型。 它只是一个普通的Ruby类,可以放在app / models /目录下的一个文件中。 如果您的模型都没有表格,并且您的应用程序中完全没有使用数据库或ActiveRecord,请确保修改您的environment.rb文件以具有以下行:
config.frameworks -= [:active_record]
这应该在Rails::Initializer.run do |config|
块。
你应该签出PassiveRecord插件。 它为您提供了一个非数据库模型的类似于ActiveRecord的界面。 这很简单,而不是打ActiveRecord的麻烦。
我们使用PassiveRecord和Validatable gem来获得OP的期望行为。