2012-02-03 14 views
16

Estoy intentando crear un modelo sin tabla de Active Record. Mi user.rb se parece a estoCómo crear el modelo sin tabla ActiveRecord en Rails 3

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 

Al crear el nuevo objeto en el controlador

@user = User.new

estoy consiguiendo el error

mysql2 :: Error: Tabla 'Sampledb.users' no existe: VER CAMPOS DE users

+1

¿Por qué necesita sin tablas modelo. ¿Simplemente puede simplemente tener una clase de ruby ​​en su lugar? Y si necesita una funcionalidad que no sea de base de datos y el uso de Rails3, puede ver mi respuesta. – ducktyped

Respuesta

8

Pocas cosas:

primer lugar que está utilizando el enfoque esbozado en Rails2 Railscast 193 cuando en realidad debería estar utilizando los carriles 3 enfoque, esbozado en Railscast 219

Es probable que no desea heredar de ActiveRecord :: Base cuando se hace este tipo de cosas.

Lea Yehuda Katz's blog post en esto.

+0

+1 para explicar que el OP no desea heredar de ActiveRecord :: Base Y para mostrar qué hacer en lugar de Rails 3. No había visto la publicación de Katz antes: tiene extensiones útiles para Ryan's Railcast 219.Gracias por eso. –

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

Esto es esencialmente lo que se explica en http://railscasts.com/episodes/219-active-model?view=asciicast con algunas campanas y silbatos añadidos, pero son lindos campanillas y silbatos. –

+0

¡Esto es realmente genial! gracias. – Derek

+1

En Rails 4 también hay ActiveModel :: Model, que incluye muchos de los módulos de ActiveModel y alguna otra magia, para hacerle sentir su modelo (no persistente o persistente) como un modelo de ActiveRecord. – nandinga

0

No heredes tu clase de ActiveRecord::Base.
Si un modelo hereda de ActiveRecord :: Base como esperaría una clase de modelo, quiere tener un back-end de base de datos.

0

Basta con retirar:

class_inheritable_accessor :columns 

y debería funcionar, incluso con asociaciones al igual que un modelo con una mesa.

0

Solo para cualquiera que todavía tenga problemas con esto. Para rieles 2.xx

class TestImp < ActiveRecord::Base 

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

para los carriles 3.1.x Puede incluir ActiveModel (según lo explicado por @ducktyped) sin heredar de ActiveRecord o Si necesita heredar de ActiveRecord :: Base debido a alguna razón, entonces lo anterior con una otra adición:

class TestImp < ActiveRecord::Base 

    def attributes_from_column_definition 
    [] 
    end 

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

para los carriles> = 3,2 no es el activerecord-tableless joya. Es una joya para crear modelos ActiveRecord sin tablas, por lo que tiene soporte para validaciones, asociaciones, tipos.

Cuando está utilizando la forma recomendada de hacerlo en Rails 3.x, no hay soporte para asociaciones ni tipos.

1

Como se ha mencionado por stephenmurdoch en rieles 3.0+ se puede utilizar el método descrito en railscasts 219

tuviera que hacer una ligera modificación a conseguir que esto funcione:

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