update rails inner includes active activerecord ruby-on-rails-2

rails - ActiveRecord:: Base sin tabla



ruby rails active record (8)

Esto surgió hace un momento ( atributos del modelo de rieles sin la columna correspondiente en db ) pero parece que el complemento de Rails mencionado no se mantiene ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ). ¿No hay forma de hacer esto con ActiveRecord como está?

Si no, ¿hay alguna manera de obtener las reglas de validación de ActiveRecord sin usar ActiveRecord?

ActiveRecord quiere que la tabla exista, por supuesto.



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 bar: nil> >> foo.valid? => false >> foo.errors => #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can''t be blank"]}, @base=#<Foo bar: nil>>


Este es un formulario de búsqueda que presenta un objeto llamado criterio que tiene un objeto de período anidado con atributos de inicio y fin .

La acción en el controlador es realmente simple, pero carga valores de objetos anidados en el formulario y vuelve a renderizar los mismos valores con mensajes de error si es necesario.

Works on Rails 3.1.

El modelo:

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

En el controlador:

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

En el ayudante:

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

En la 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 el HTML:

<form action="/admin/search" id="new_criteria" method="post"> <input id="criteria_period_attributes_beginning_as_text" name="criteria[period_attributes][beginning_as_text]" type="text"> <input id="criteria_period_attributes_end_as_text" name="criteria[period_attributes][end_as_text]" type="text">

Nota : El atributo de acción proporcionado por el helper y el formato de nomenclatura de atributos anidados hace que sea tan simple para el controlador cargar todos los valores a la vez


Hay la gema activerecord-tableless . Es una joya para crear modelos ActiveRecord sin tablas, por lo que tiene soporte para validaciones, asociaciones, tipos. Es compatible con Active Record 2.3, 3.0, 3.2

La forma recomendada de hacerlo en Rails 3.x (utilizando ActiveModel) no admite asociaciones ni tipos.


Las validaciones son simplemente un módulo dentro de ActiveRecord. ¿Has intentado mezclarlos en tu modelo que no es ActiveRecord?

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


Me imagino que cuantas más respuestas, mejor, ya que este es uno de los primeros resultados en google al buscar "modelos Rails 3.1 sin tablas"

Implementé lo mismo sin usar ActiveRecord :: Base mientras incluía ActiveRecord :: Validations

El objetivo principal era hacer que todo funcionara de manera formidable, y a continuación he incluido un pago de muestra que no se guardará en ningún lado pero que aún tiene la capacidad de ser validado utilizando las validaciones que todos conocemos y amamos.

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

Espero que esto ayude a alguien ya que he pasado unas horas tratando de resolver esto hoy.


Solo una adición a la respuesta aceptada:

Haga que sus subclases hereden las columnas principales 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


ACTUALIZACIÓN: para Rails 3 esto se puede hacer muy fácil. En Rails 3+ puede usar el nuevo módulo ActiveModel y sus submódulos. Esto debería funcionar ahora:

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

Para obtener más información, puede consultar el Railscast (o leer sobre él en AsciiCasts ) sobre el tema, así como esta publicación de blog de Yehuda Katz .

ANTIGUA RESPUESTA SIGUE:

Es posible que deba agregar esto a la solución, propuesta por John Topley en el comentario anterior:

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

Esto le proporciona un nombre de tabla "falso", si lo necesita. Sin este método, Foo::table_name table_name evaluará a "tablelesses".