Ruby-on-rails 没有数据库的 Rails 模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/315850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails model without database
提问by FlipFlop
I want to create a Rails (2.1 and 2.2) model with ActiveRecord validations, but without a database table. What is the most widely used approach? I've found some plugins that claim to offer this functionality, but many of them don't appear to be widely used or maintained. What does the community recommend I do? Right now I am leaning toward coming up with my own solution based on this blog post.
我想创建一个带有 ActiveRecord 验证的 Rails(2.1 和 2.2)模型,但没有数据库表。使用最广泛的方法是什么?我发现了一些声称提供此功能的插件,但其中许多似乎并未得到广泛使用或维护。社区建议我做什么?现在我倾向于根据这篇博文提出我自己的解决方案。
采纳答案by Honza
I think the blog post you are linking is the best way to go. I would only suggest moving the stubbed out methods into a module not to pollute your code.
我认为您链接的博客文章是最好的方法。我只建议将被剔除的方法移动到一个模块中,以免污染您的代码。
回答by d135-1r43
There is a better way to do this in Rails 3: http://railscasts.com/episodes/219-active-model
在 Rails 3 中有更好的方法来做到这一点:http: //railscasts.com/episodes/219-active-model
回答by John Topley
This is an approach I have used in the past:
这是我过去使用的一种方法:
In app/models/tableless.rb
在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
In app/models/foo.rb
在app/models/foo.rb
class Foo < Tableless
column :bar, :string
validates_presence_of :bar
end
In script/console
在脚本/控制台中
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>>
回答by hlcs
There is easier way now:
现在有更简单的方法:
class Model
include ActiveModel::Model
attr_accessor :var
validates :var, presence: true
end
ActiveModel::Modelcode:
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
回答by tpinto
just create a new file ending in ".rb" following the conventions you're used to (singular for file name and class name, underscored for file name, camel case for class name) on your "models/" directory. The key here is to not inherit your model from ActiveRecord (because it is AR that gives you the database functionality). e.g.: for a new model for cars, create a file called "car.rb" in your models/ directory and inside your model:
只需按照您习惯的约定(文件名和类名的单数,文件名下划线,类名的驼峰式命名)在“models/”目录中创建一个以“.rb”结尾的新文件。这里的关键是不要从 ActiveRecord 继承您的模型(因为是 AR 为您提供了数据库功能)。例如:对于汽车的新模型,在模型/目录和模型内部创建一个名为“car.rb”的文件:
class Car
# here goes all your model's stuff
end
edit: btw, if you want attributes on your class, you can use here everything you use on ruby, just add a couple lines using "attr_accessor":
编辑:顺便说一句,如果你想要你的类的属性,你可以在这里使用你在 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
edit #2: after reading Mike's comment, I'd tell you to go his way if you want all of the ActiveRecord's functionality but no table on the database. If you just want an ordinary Ruby class, maybe you'll find this solution better ;)
编辑 #2:阅读 Mike 的评论后,如果您想要 ActiveRecord 的所有功能但数据库中没有表,我会告诉您按照他的方式进行。如果你只想要一个普通的 Ruby 类,也许你会发现这个解决方案更好;)
回答by xmjw
For the sake of completeness:
为了完整起见:
Rails now (at V5) has a handy module you can include:
Rails 现在(在 V5 中)有一个方便的模块,您可以包括:
include ActiveModel::Model
include ActiveModel::Model
This allows you to initialise with a hash, and use validations amongst other things.
这允许您使用散列进行初始化,并在其他方面使用验证。
Full documentation is here.
完整文档在这里。
回答by Will Marshall
I have built a quick Mixin to handle this, as per John Topley's suggestion.
根据 John Topley 的建议,我已经构建了一个快速的 Mixin 来处理这个问题。
回答by Laurent Farcy
There's a screencastabout non-Active Record model, made up by Ryan Bates. A good place to start from.
有一个关于非 Active Record 模型的截屏视频,由 Ryan Bates 制作。一个很好的起点。
Just in case you did not already watch it.
以防万一你还没有看过。
回答by Mike Breen
What about marking the class as abstract?
将类标记为抽象怎么样?
class Car < ActiveRecord::Base
self.abstract = true
end
this will tell rails that the Car class has no corresponding table.
这将告诉 rails Car 类没有对应的表。
[edit]
[编辑]
this won't really help you if you'll need to do something like:
如果您需要执行以下操作,这不会真正帮助您:
my_car = Car.new
回答by Mike Breen
Use the Validatable gem. As you say, there are AR-based solutions, but they tend to be brittle.
使用 Validatable gem。正如你所说,有基于 AR 的解决方案,但它们往往很脆弱。

