没有数据库的Rails模型

时间:2008-11-24 23:18:57

标签: ruby-on-rails ruby activerecord

我想使用ActiveRecord验证创建Rails(2.1和2.2)模型,但没有数据库表。什么是最广泛使用的方法?我发现一些声称提供此功能的插件,但其中许多插件似乎没有得到广泛使用或维护。社区推荐我做什么?现在我倾向于根据this blog post提出我自己的解决方案。

13 个答案:

答案 0 :(得分:67)

在Rails 3中有更好的方法:http://railscasts.com/episodes/219-active-model

答案 1 :(得分:43)

这是我过去使用的一种方法:

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>>

答案 2 :(得分:16)

现在有更简单的方法:

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

答案 3 :(得分:8)

按照您习惯使用的约定(文件名和类名称的单数,文件名的下划线,类名称的驼峰大小写)在“models /”目录下创建一个以“.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类,也许你会更好地找到这个解决方案;)

答案 4 :(得分:8)

我认为你链接的博客文章是最好的方式。我只建议将存根方法移到模块中,以免污染您的代码。

答案 5 :(得分:5)

为了完整起见:

Rails现在(在V5)有一个方便的模块,你可以包括:

include ActiveModel::Model

这允许您使用哈希初始化,并使用其他方面的验证。

完整文档为here

答案 6 :(得分:4)

有一个screencast关于非活动记录模型,由Ryan Bates组成。一个好的起点。

万一你还没看过它。

答案 7 :(得分:3)

根据John Topley的建议,我已经建立了一个快速的Mixin来处理这个问题。

http://github.com/willrjmarshall/Tableless

答案 8 :(得分:2)

将类标记为抽象怎么样?

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

这将告诉rails Car类没有相应的表。

[编辑]

如果您需要执行以下操作,这将无法真正帮助您:

my_car = Car.new

答案 9 :(得分:2)

使用Validatable gem。正如你所说,有基于AR的解决方案,但它们往往很脆弱。

http://validatable.rubyforge.org/

答案 10 :(得分:1)

有人试图在非Active Record类中包含ActiveRecord::ValidationsActiveRecord::Validations::ClassMethods,看看尝试设置验证器时会发生什么?

我确信验证框架和ActiveRecord本身之间存在大量依赖关系。但是,您可以通过从AR验证框架中分配自己的验证框架来成功摆脱这些依赖关系。

只是一个想法。

更新:oopps,这或多或少与您的问题相关联的帖子中的建议。对不起,请原谅。

答案 11 :(得分:0)

就像Tiago Pinto说的那样,只是没有你的模型继承自ActiveRecord :: Base。它只是一个常规的Ruby类,您可以将其粘贴到app / models /目录中的文件中。如果您的模型都没有表,并且您的应用中根本没有使用数据库或ActiveRecord,请务必修改environment.rb文件以使其具有以下行:

config.frameworks -= [:active_record]

这应该在Rails::Initializer.run do |config|区块内。

答案 12 :(得分:0)

您应该查看PassiveRecord插件。它为非数据库模型提供了类似ActiveRecord的接口。这比打击ActiveRecord简单,麻烦少。

我们将PassiveRecord与Validatable gem结合使用,以获得OP所期望的行为。

相关问题