2012-02-03 21 views
16

Próbuję stworzyć tableless Active Record. Moja user.rb wygląda toJak utworzyć tableless ActiveRecord w Railsach 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 

Podczas tworzenia nowego obiektu w kontrolerze

@user = User.new

Dostaję błędu

Mysql2 :: Error: Tabela 'Sampledb.users' nie istnieje: Lista pól z users

+1

Dlaczego musisz tableless Model. Możesz po prostu zamiast tego mieć klasę ruby? A jeśli potrzebujesz funkcji innej niż baza danych i korzystania z Rails3, możesz zobaczyć moją odpowiedź w dół. – ducktyped

Odpowiedz

8

kilka rzeczy:

pierwsze używasz podejście Rails2 opisaną w Railscast 193 kiedy naprawdę powinno być przy użyciu szyny 3 podejścia, przedstawionego w Railscast 219

Prawdopodobnie nie chcą dziedziczyć ActiveRecord :: Base, gdy robi tego typu rzeczy.

Przeczytaj o tym artykule Jehudy Katza: blog post.

+0

+1 za wyjaśnienie, że OP nie chce dziedziczyć z ActiveRecord :: Base AND, aby pokazać, co zrobić zamiast Rails 3. Nie widziałem wcześniej posta Katza - ma użyteczne rozszerzenia dla Railcast 219 Ryana.Dziękuję za to. –

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

Jest to w zasadzie to, co jest napisane w http://railscasts.com/episodes/219-active-model?view=asciicast z dodanymi dzwonkami i gwizdkami, ale są to ładne dzwonki i gwizdki. –

+0

To jest naprawdę świetne! Dziękuję Ci. – Derek

+1

W Railsach 4 znajduje się także ActiveModel :: Model, który zawiera wiele modułów ActiveModel i trochę innych magii, abyś czuł się swoim (nieutrzymywalnym lub niestandardowym modelem) takim jak model ActiveRecord. – nandinga

0

Nie dziedziczą swojej klasy od ActiveRecord::Base.
Jeśli model dziedziczy z ActiveRecord :: Base tak, jak można oczekiwać klasy modelu, chce mieć back-end bazy danych.

0

Wystarczy usunąć:

class_inheritable_accessor :columns 

i powinno działać, nawet ze stowarzyszeniami podobnie jak model z tabeli.

0

Dla każdego, kto wciąż z tym walczy. Na szynach 2.xx

class TestImp < ActiveRecord::Base 

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

dla szyn 3.1.x Można dołączyć ActiveModel (jak wyjaśnił @ducktyped) bez dziedziczenie z ActiveRecord lub Jeśli trzeba dziedziczą z ActiveRecord :: Base powodu jakiegoś powodu następnie powyżej z jednym dodatkowo:

class TestImp < ActiveRecord::Base 

    def attributes_from_column_definition 
    [] 
    end 

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

szyn> = 3,2 nie jest activerecord-tableless perełka. To klejnot do tworzenia bez tableless modeli ActiveRecord, dlatego ma wsparcie dla walidacji, powiązań, typów.

Gdy używasz zalecanego sposobu, aby to zrobić w Railsach 3.x, nie ma obsługi skojarzeń ani typów.

1

Jak wspomniano przez stephenmurdoch w szynach 3.0+ można użyć metody opisanych w railscasts 219

musiałem zrobić lekką modyfikację aby uzyskać to do pracy:

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 
Powiązane problemy