2012-02-03 74 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 
相關問題