Modelo de Rails sin base de datos

Quiero crear un modelo de Rails (2.1 y 2.2) con validaciones de ActiveRecord, pero sin una tabla de base de datos. ¿Cuál es el enfoque más utilizado? He encontrado algunos complementos que dicen ofrecer esta funcionalidad, pero muchos de ellos no parecen ser ampliamente utilizados o mantenidos. ¿Qué recomienda la comunidad que haga? En este momento me estoy inclinando por encontrar mi propia solución basada en esta publicación de blog .

Creo que la publicación del blog que estás enlazando es la mejor manera de hacerlo. Solo recomendaría mover los métodos apagados en un módulo para no contaminar su código.

Hay una forma mejor de hacerlo en Rails 3: http://railscasts.com/episodes/219-active-model

Este es un enfoque que he usado en el pasado:

En la aplicación / 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 

En la aplicación / modelos / foo.rb

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

En script / consola

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

Hay una manera más fácil ahora:

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

ActiveModel::Model Código de 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/classes/ActiveModel/Model.html

simplemente cree un nuevo archivo que termine en “.rb” siguiendo las convenciones a las que está acostumbrado (singular para nombre de archivo y nombre de clase, subrayado para nombre de archivo, camel case para nombre de clase) en su directorio “modelos /”. La clave aquí es no heredar su modelo de ActiveRecord (porque es AR lo que le da la funcionalidad de la base de datos). por ejemplo: para un nuevo modelo de automóvil, cree un archivo llamado “car.rb” en su directorio de modelos / y dentro de su modelo:

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

edit: por cierto, si quieres atributos en tu clase, puedes usar aquí todo lo que usas en ruby, solo agrega un par de líneas 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 

edición # 2: después de leer el comentario de Mike, te diría que sigas su camino si quieres todas las funcionalidades de ActiveRecord pero no hay ninguna tabla en la base de datos. Si solo quieres una clase de Ruby común, tal vez encuentres esta solución mejor;)

Hay un screencast sobre el modelo de registro no activo, compuesto por Ryan Bates. Un buen lugar para comenzar.

En caso de que no lo hayas visto ya.

En aras de la exhaustividad:

Rails ahora (en V5) tiene un módulo práctico que puede incluir:

include ActiveModel::Model

Esto le permite inicializar con un hash y usar validaciones, entre otras cosas.

La documentación completa está aquí .

He construido un Mixin rápido para manejar esto, según la sugerencia de John Topley.

http://github.com/willrjmarshall/Tableless

¿Qué hay de marcar la clase como abstracto?

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

esto le dirá a los Rails que la clase Auto no tiene una tabla correspondiente.

[editar]

esto realmente no te ayudará si necesitarás hacer algo como:

 my_car = Car.new 

Usa la gem Validatable. Como dices, existen soluciones basadas en AR, pero tienden a ser frágiles.

http://validatable.rubyforge.org/

¿Alguna vez alguien ha intentado incluir ActiveRecord::Validations y ActiveRecord::Validations::ClassMethods en una clase de registro no activo y ver qué ocurre cuando se intentan configurar validadores?

Estoy seguro de que hay muchas dependencias entre el marco de validación y el propio ActiveRecord. Pero puede tener éxito en deshacerse de esas dependencias al bifurcar su propio marco de validación desde el marco de validación de AR.

Solo una idea.

Actualización : oopps, esto es más o menos lo que se sugiere en la publicación vinculada a su pregunta. Disculpe las molestias.

Haga lo que dijo Tiago Pinto y simplemente no haga que su modelo herede de ActiveRecord :: Base. Simplemente será una clase regular de Ruby que colocará en un archivo en su aplicación / modelos / directorio. Si ninguno de sus modelos tiene tablas y no está utilizando una base de datos o ActiveRecord en su aplicación, asegúrese de modificar su archivo environment.rb para tener la siguiente línea:

 config.frameworks -= [:active_record] 

Esto debería estar dentro de Rails::Initializer.run do |config| bloquear.

Deberías pagar el complemento PassiveRecord . Le brinda una interfaz similar a ActiveRecord para modelos que no son de base de datos. Es simple y menos complicado que luchar contra ActiveRecord.

Estamos usando PassiveRecord en combinación con la gem Validatable para obtener el comportamiento deseado de OP.