2012-02-03 101 views
16

我正在尝试创建一个Active Record无表模型。我user.rb看起来像这样如何在Rails 3中创建ActiveRecord无表模型

class User < ActiveRecord::Base 

    class_inheritable_accessor :columns 

    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 


    column :name, :text 
    column :exception, :text 
    serialize :exception  
end 

当控制器创建新的对象

@user = User.new

我收到错误

Mysql2 ::错误:表'Sampledb.users'不存在:SHOW FIELDS FROM users

+1

为什么你需要无表模型。你可以简单地有一个红宝石班呢?如果你需要非数据库功能并使用Rails3,你可以看到我的答案。 – ducktyped 2012-02-03 05:22:06

回答

8

几件事:

首先使用的是在Railscast 193概述当你真正应该使用Rails 3的方法的Rails2办法,Railscast 219

列出你可能不希望做这样的事情,当从ActiveRecord的:: Base的继承。

阅读Yehuda Katz的blog post就可以了。

+0

+1,因为它解释说OP不想从ActiveRecord :: Base继承,而是为Rails 3显示做什么。我之前没有看到Katz的帖子 - 它对Ryan的Railcast 219有用。谢谢你。 – 2012-09-05 18:28:44

32
class Tableless 

    include ActiveModel::Validations 
    include ActiveModel::Conversion 
    extend ActiveModel::Naming 

    def self.attr_accessor(*vars) 
    @attributes ||= [] 
    @attributes.concat(vars) 
    super 
    end 

def self.attributes 
    @attributes 
end 

def initialize(attributes={}) 
    attributes && attributes.each do |name, value| 
    send("#{name}=", value) if respond_to? name.to_sym 
    end 
end 

def persisted? 
    false 
end 

def self.inspect 
    "#<#{ self.to_s} #{ self.attributes.collect{ |e| ":#{ e }" }.join(', ') }>" 
end 

end 
+1

这实际上是在http://railscasts.com/episodes/219-active-model?view=asciicast中加上一些额外的铃声和哨声,但它们是很好的花里胡哨的东西。 – 2012-09-05 18:25:16

+0

这真的太棒了!谢谢。 – Derek 2013-12-05 18:44:56

+1

在Rails 4中,还有ActiveModel :: Model,其中包含许多ActiveModel模块和一些其他魔术,以使您感觉像ActiveRecord模型那样的您的(非持久性或自定义持久性)模型。 – nandinga 2014-09-17 12:49:04

0

不要从ActiveRecord::Base继承您的班级。
如果模型继承自ActiveRecord :: Base,就像您希望模型类一样,它希望有一个数据库后端。

0

只是删除:

class_inheritable_accessor :columns 

,它应该工作,即使有关联,就像一个表的模型。

0

只为任何人仍然在与此挣扎。对于轨道2.xx的

class TestImp < ActiveRecord::Base 

    def self.columns 
    @columns ||= [] 
    end 
end 

钢轨3.1.X您可以加载ActiveModel包括(由@ducktyped解释)没有继承ActiveRecord或者如果你需要从ActiveRecord的:: Base的继承,由于某种原因,然后与一种其它添加上述:

class TestImp < ActiveRecord::Base 

    def attributes_from_column_definition 
    [] 
    end 

    def self.columns 
    @columns ||= [] 
    end 
end 
0

对于滑轨> = 3.2存在activerecord-tableless宝石。它是创建无表ActiveRecord模型的宝石,因此它支持验证,关联和类型。

当您在Rails 3.x中使用推荐的方法时,不支持关联和类型。

1

轨3.0+您可以使用该方法在railscasts 219

概述提及stephenmurdoch我不得不作出轻微修改得到这个工作:

class Message 
    include ActiveModel::Validations 
    include ActiveModel::Conversion 
    extend ActiveModel::Naming 

    attr_accessor :name, :email, :content 

    validates_presence_of :name 
    validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i 
    validates_length_of :content, :maximum => 500 

    def initialize(attributes = {}) 
    unless attributes.nil? 
     attributes.each do |name, value| 
     send("#{name}=", value) 
     end 
    end 
    end 

    def persisted? 
    false 
    end 
end 
相关问题