ActiveRecord :: Base senza tabella

Questo è venuto fuori un po ‘fa ( attributi del modello di rota senza colonna corrispondente in db ) ma sembra che il plugin Rails menzionato non sia mantenuto ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ). Non c’è modo di farlo con ActiveRecord così com’è?

In caso contrario, esiste un modo per ottenere le regole di convalida di ActiveRecord senza utilizzare ActiveRecord?

ActiveRecord vuole che la tabella esista, ovviamente.

Questo è un approccio che ho usato in passato:

In app / models / tableless.rb

class Tableless < ActiveRecord::Base 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 # Override the save method to prevent exceptions. def save(validate = true) validate ? valid? : true end end 

In app / models / foo.rb

 class Foo < Tableless column :bar, :string validates_presence_of :bar end 

In script / console

 Loading development environment (Rails 2.2.2) >> foo = Foo.new => # >> foo.valid? => false >> foo.errors => #["can't be blank"]}, @base=#> 

Le convalide sono semplicemente un modulo all’interno di ActiveRecord. Hai provato a mescolarli con il tuo modello non ActiveRecord?

 class MyModel include ActiveRecord::Validations # ... end 

Immagino che più risposte sono migliori, visto che questo è uno dei primi risultati su google durante la ricerca di “modelli di rails 3.1 senza tabelle”

Ho implementato la stessa cosa senza usare ActiveRecord :: Base includendo anche ActiveRecord :: Validations

L’objective principale era quello di ottenere tutto ciò che funziona in formtastic, e di seguito ho incluso un pagamento di esempio che non verrà salvato da nessuna parte, ma ha ancora la possibilità di essere convalidato utilizzando le convalide che tutti conosciamo e amiamo.

 class Payment include ActiveModel::Validations attr_accessor :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state, :zip_code, :home_telephone, :email, :new_record validates_presence_of :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state def initialize(options = {}) if options.blank? new_record = true else new_record = false end options.each do |key, value| method_object = self.method((key + "=").to_sym) method_object.call(value) end end def new_record? return new_record end def to_key end def persisted? return false end end 

Spero che questo aiuti qualcuno come ho passato alcune ore cercando di capirlo oggi.

AGGIORNAMENTO: per Rails 3 questo può essere fatto molto facile. In Rails 3+ puoi usare il nuovo modulo ActiveModel e i suoi sottomoduli. Questo dovrebbe funzionare ora:

 class Tableless include ActiveModel::Validations attr_accessor :name validates_presence_of :name end 

Per maggiori informazioni, è ansible controllare il Railscast (o leggere su di esso su AsciiCasts ) sull’argomento, così come questo post del blog di Yehuda Katz .

VECCHIE RISPOSTE SEGUONO:

Potrebbe essere necessario aggiungere questo alla soluzione, proposta da John Topley nel commento precedente:

 class Tableless class << self def table_name self.name.tableize end end end class Foo < Tableless; end Foo.table_name # will return "foos" 

Questo ti fornisce un nome di tabella "falso", se ne hai bisogno. Senza questo metodo, Foo::table_name valuterà "tablelesses".

Ho trovato questo link che funziona BELLISSIMO.

http://codetunes.com/2008/07/20/tableless-models-in-rails/

Solo un’aggiunta alla risposta accettata:

Fai in modo che le sottoclassi ereditino le colonne parent con:

 class FakeAR < ActiveRecord::Base def self.inherited(subclass) subclass.instance_variable_set("@columns", columns) super end 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 # Overrides save to prevent exceptions. def save(validate = true) validate ? valid? : true end end 

Questo è un modulo di ricerca che presenta un object chiamato criteri che ha un object periodo nidificato con attributi iniziali e finali .

L’azione nel controller è davvero semplice, tuttavia carica valori da oggetti nidificati sul modulo e re-rende gli stessi valori con i messaggi di errore, se necessario.

Funziona su Rails 3.1.

Il modello:

 class Criteria < ActiveRecord::Base class << self def column_defaults {} end def column_names [] end end # of class methods attr_reader :period def initialize values values ||= {} @period = Period.new values[:period] || {} super values end def period_attributes @period end def period_attributes= new_values @period.attributes = new_values end end 

Nel controller:

 def search @criteria = Criteria.new params[:criteria] end 

Nell'assistente:

 def criteria_index_path ct, options = {} url_for :action => :search end 

Nella vista:

 <%= form_for @criteria do |form| %> <%= form.fields_for :period do |prf| %> <%= prf.text_field :beginning_as_text %> <%= prf.text_field :end_as_text %> <% end %> <%= form.submit "Search" %> <% end %> 

Produce l'HTML:

 

Nota : l'attributo action fornito dall'helper e il formato di denominazione degli attributi nidificati che rende così semplice per il controller caricare tutti i valori contemporaneamente

C’è la gem activerecord-tableless . È un gioiello creare modelli ActiveRecord senza tablature, quindi ha supporto per convalide, associazioni, tipi. Supporta Active Record 2.3, 3.0, 3.2

Il modo consigliato di farlo in Rails 3.x (usando ActiveModel) non ha supporto per associazioni o tipi.