2012-02-03 20 views
16

Sto provando a creare un modello senza tabulazione Active Record. Il mio user.rb assomiglia a questoCome creare il modello senza tabulazione ActiveRecord in 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 

Quando si crea il nuovo oggetto controller

@user = User.new

sto ottenendo l'errore

Mysql2 :: Errore: Tabella 'Sampledb.users' non esiste: MOSTRA CAMPI DA users

+1

Perché avete bisogno tableless modello. Puoi semplicemente semplicemente avere una classe di rubino, invece? E se hai bisogno di funzionalità non di database e utilizzo di Rails3, puoi vedere la mia risposta in basso. – ducktyped

risposta

8

Poche cose:

In primo luogo si sta utilizzando l'approccio delineato nella Rails2 Railscast 193 quando in realtà si dovrebbe utilizzare Rails 3 approccio, delineato nella Railscast 219

Probabilmente non si vuole ereditare da ActiveRecord :: Base quando si fa questo genere di cose.

Leggi Yehuda Katz's blog post su questo.

+0

+1 per spiegare che l'OP non vuole ereditare da ActiveRecord :: Base E per mostrare cosa fare invece per Rails 3. Non avevo ancora visto il post di Katz - ha estensioni utili a Ryan's Railcast 219.Grazie per questo. –

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

Questo è essenzialmente ciò che è spiegato in http://railscasts.com/episodes/219-active-model?view=asciicast con alcune campane e fischietti aggiunti, ma sono belle campane e fischietti. –

+0

Questo è davvero fantastico! grazie. – Derek

+1

In Rails 4 c'è anche ActiveModel :: Model, che include molti dei moduli ActiveModel e qualche altra magia, per farti sentire il tuo modello (non persistente o persistentemente personalizzato) come un modello ActiveRecord. – nandinga

0

non ereditiamo la classe da ActiveRecord::Base.
Se un modello eredita da ActiveRecord :: Base come ci si aspetterebbe da una classe del modello, desidera avere un back-end del database.

0

sufficiente rimuovere:

class_inheritable_accessor :columns 

e dovrebbe funzionare, anche con le associazioni, proprio come un modello con un tavolo.

0

Solo per chi ancora fatica con questo. Per rotaie 2.xx

class TestImp < ActiveRecord::Base 

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

per Rails 3.1.x è possibile sia inserire ActiveModel (come spiegato da @ducktyped) senza che eredita da ActiveRecord o Se si ha bisogno di ereditare da ActiveRecord :: Base causa di qualche ragione, allora Quanto sopra con un altro più:

class TestImp < ActiveRecord::Base 

    def attributes_from_column_definition 
    [] 
    end 

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

Per Rails> = 3.2 c'è la activerecord-tableless gemma. È un gioiello per creare modelli ActiveRecord senza tablature, quindi ha supporto per convalide, associazioni, tipi.

Quando si utilizza il modo consigliato di farlo in Rails 3.x non è disponibile alcun supporto per associazione o tipi.

1

Come menzionato da stephenmurdoch in rotaie 3.0+ è possibile utilizzare il metodo descritto in railscasts 219

ho dovuto fare una leggera modifica per arrivare a questo lavoro:

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