Pergunta

Este veio um pouco atrás ( trilhos atributos modelo, sem coluna correspondente no db ), mas parece que as Rails plugin é mencionados não conservado ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ). Não há nenhuma maneira de fazer isso com ActiveRecord como é?

Se não, há alguma maneira de obter regras de validação ActiveRecord sem usar ActiveRecord?

ActiveRecord quer a tabela de existir, é claro.

Foi útil?

Solução

Esta é uma abordagem que tenho usado no passado:

Em 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

Em app / models / foo.rb

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

Em script / console

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

Outras dicas

As validações são simplesmente um módulo dentro ActiveRecord. Você tentou misturar-los em seu modelo não-ActiveRecord?

class MyModel
  include ActiveRecord::Validations

  # ...
end

Eu acho que as respostas mais melhor uma vez que este é um dos primeiros resultados no Google ao procurar por "trilhos 3.1 modelos sem tabelas"

Eu tenho implementa a mesma coisa sem usar ActiveRecord :: Base, enquanto incluindo os ActiveRecord :: validações

O principal objetivo era conseguir tudo que trabalham em Formtastic, e abaixo eu incluí um pagamento amostra que não vai ser salvo em qualquer lugar, mas ainda tem a capacidade de ser validado usando as validações que todos nós conhecemos e 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 isso ajude alguém como eu passei algumas horas tentando descobrir isso hoje.

UPDATE: Para Rails 3 isto pode ser feito muito fácil. No Rails 3 + você pode usar o novo módulo ActiveModel e seus submódulos. Isso deve funcionar agora:

class Tableless
  include ActiveModel::Validations

  attr_accessor :name

  validates_presence_of :name
end

Para obter mais informações, você pode conferir o Railscast (ou ler sobre ele em AsciiCasts ) sobre o tema, assim como este blog por Yehuda Katz .

RESPOSTA VELHO SEGUINTE:

Você pode precisar adicionar esta à solução, proposta por John Topley no comentário anterior:

class Tableless

  class << self
    def table_name
      self.name.tableize
    end
  end

end

class Foo < Tableless; end
Foo.table_name # will return "foos"

Isto proporciona-lhe um "fake" nome da tabela, se você precisa de um. Sem este método, Foo::table_name irá avaliar a "tablelesses".

Eu encontrei este link que funciona lindamente.

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

Apenas um complemento para a resposta aceita:

Faça suas subclasses herdam as colunas pai com:

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

Este é um formulário de pesquisa que apresenta um objeto chamado critérios que tem um período objeto aninhado com início e final atributos.

A ação no controlador é realmente simples, mas ele carrega valores de objetos aninhados no formulário e re-processa os mesmos valores com mensagens de erro, se necessário.

Os trabalhos no Rails 3.1.

O 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

No controlador:

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

No helper:

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

Do ponto de 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 %>

Produz o 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 : O atributo action fornecido pelo ajudante e os atributos aninhados formato que faz de nomeação tão simples para o controlador para carregar todos os valores de uma só vez

o activerecord-tableless gem . É uma jóia para criar modelos tableless ActiveRecord, então ele tem suporte para validações, associações, tipos. Ele suporta Active Record 2.3, 3.0, 3.2

A maneira recomendada para fazê-lo em Rails 3.x (usando ActiveModel) não tem suporte para associações nem tipos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top