Modello di rotaie senza database

Voglio creare un modello Rails (2.1 e 2.2) con convalida ActiveRecord, ma senza una tabella di database. Qual è l’approccio più diffuso? Ho trovato alcuni plugin che affermano di offrire questa funzionalità, ma molti di essi non sembrano essere ampiamente utilizzati o mantenuti. Cosa consiglia la comunità che faccio? In questo momento sono propenso a venire con la mia soluzione basata su questo post del blog .

Penso che il post sul blog che stai collegando sia il modo migliore per andare. Vorrei solo suggerire di spostare i metodi stoppati in un modulo per non inquinare il tuo codice.

C’è un modo migliore per farlo in Rails 3: http://railscasts.com/episodes/219-active-model

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=#> 

C’è modo più semplice ora:

 class Model include ActiveModel::Model attr_accessor :var validates :var, presence: true end 

ActiveModel::Model Codice ActiveModel::Model :

 module ActiveModel module Model def self.included(base) base.class_eval do extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::Validations include ActiveModel::Conversion end end def initialize(params={}) params.each do |attr, value| self.public_send("#{attr}=", value) end if params end def persisted? false end end end 

http://api.rubyonrails.org/classs/ActiveModel/Model.html

basta creare un nuovo file che termina in “.rb” seguendo le convenzioni a cui sei abituato (singolare per nome file e nome class, sottolineato per nome file, caso cammello per nome class) nella tua directory “models /”. La chiave qui è di non ereditare il tuo modello da ActiveRecord (perché è AR che ti dà la funzionalità del database). ad esempio: per un nuovo modello per auto, crea un file chiamato “car.rb” nella tua cartella / modelli e all’interno del tuo modello:

 class Car # here goes all your model's stuff end 

edit: btw, se vuoi attributi sulla tua class, puoi usare qui tutto ciò che usi su ruby, basta aggiungere un paio di linee usando “attr_accessor”:

 class Car attr_accessor :wheels # this will create for you the reader and writer for this attribute attr_accessor :doors # ya, this will do the same # here goes all your model's stuff end 

modifica # 2: dopo aver letto il commento di Mike, ti direi di andare per la sua strada se vuoi tutte le funzionalità di ActiveRecord ma nessuna tabella sul database. Se vuoi solo una normale lezione di Ruby, forse troverai questa soluzione migliore;)

C’è uno screencast sul modello di Record non attivo, composto da Ryan Bates. Un buon punto di partenza.

Nel caso non lo avessi già guardato.

Per amor di completezza:

Rails ora (in V5) ha un pratico modulo che puoi includere:

include ActiveModel::Model

Questo ti permette di inizializzare con un hash e usare validazioni tra le altre cose.

La documentazione completa è qui .

Ho creato un rapido Mixin per gestirlo, come suggerito da John Topley.

http://github.com/willrjmarshall/Tableless

Che dire della marcatura della class come astratta?

 class Car < ActiveRecord::Base self.abstract = true end 

questo dirà ai binari che la class Car non ha una tabella corrispondente.

[modificare]

questo non ti aiuterà veramente se avrai bisogno di fare qualcosa del tipo:

 my_car = Car.new 

Usa la gem Validabile. Come dici tu, ci sono soluzioni basate su AR, ma tendono ad essere fragili.

http://validatable.rubyforge.org/

Qualcuno ha mai provato ad includere ActiveRecord::Validations e ActiveRecord::Validations::ClassMethods in una class Record non triggers e vedere cosa succede quando si tenta di impostare i validatori?

Sono sicuro che ci sono molte dipendenze tra il framework di validazione e ActiveRecord stesso. Ma si può riuscire a sbarazzarsi di tali dipendenze mediante la forgiatura del proprio framework di convalida dal framework di convalida AR.

Solo un’idea

Aggiornamento : oopps, questo è più o meno ciò che è suggerito nel post collegato con la tua domanda. Scusa per il disturbo.

Fai come ha detto Tiago Pinto e non fare in modo che il tuo modello erediti da ActiveRecord :: Base. Sarà solo una normale lezione di Ruby che incollerai in un file nella tua app / models / directory. Se nessuno dei tuoi modelli ha tabelle e non stai utilizzando un database o ActiveRecord nella tua app, assicurati di modificare il file environment.rb in modo che abbia la seguente riga:

 config.frameworks -= [:active_record] 

Questo dovrebbe essere all’interno di Rails::Initializer.run do |config| bloccare.

Dovresti controllare il plugin PassiveRecord . Ti offre un’interfaccia simile a ActiveRecord per i modelli non di database. È semplice e meno problematico rispetto alla lotta contro ActiveRecord.

Usiamo PassiveRecord in combinazione con la gem Validable per ottenere il comportamento desiderato dall’OP.