ActiveRecord:: Base без таблицы
Это немного изменилось (атрибуты модели rails без соответствующего столбца в db), но похоже, что упомянутый плагин Rails не поддерживается (http://agilewebdevelopment.com/plugins/activerecord_base_without_table). Нет ли способа сделать это с помощью ActiveRecord?
Если нет, есть ли способ получить правила проверки ActiveRecord без использования ActiveRecord?
ActiveRecord хочет, чтобы таблица существовала, конечно.
Ответы
Ответ 1
Это подход, который я использовал в прошлом:
В приложении /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
В приложении /models/foo.rb
class Foo < Tableless
column :bar, :string
validates_presence_of :bar
end
В 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>>
Ответ 2
Валидации - это просто модуль в ActiveRecord. Вы пытались смешивать их в своей модели без ActiveRecord?
class MyModel
include ActiveRecord::Validations
# ...
end
Ответ 3
Я получаю больше ответов, так как это один из первых результатов в google при поиске "рельсов 3.1 моделей без таблиц"
Я реализую то же самое без использования ActiveRecord:: Base, включая ActiveRecord:: Validations
Основная цель заключалась в том, чтобы все работало в formtastic, и ниже я включил пример оплаты, который не будет сохранен нигде, но все же будет иметь возможность быть подтвержденным с помощью валидаций, которые все мы знаем и любим.
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
Я надеюсь, что это поможет кому-то, поскольку я потратил несколько часов, пытаясь понять это сегодня.
Ответ 4
UPDATE: Для Rails 3 это можно сделать очень просто. В Rails 3+ вы можете использовать новый модуль ActiveModel
и его подмодули. Теперь это должно работать:
class Tableless
include ActiveModel::Validations
attr_accessor :name
validates_presence_of :name
end
Для получения дополнительной информации вы можете проверить Railscast (или читал об этом на AsciiCasts) по этой теме, а также этот сообщение в блоге от Yehuda Katz.
OLD ANSWER FOLLOWS:
Возможно, вам придется добавить это в решение, предложенное Джоном Топли в предыдущем комментарии:
class Tableless
class << self
def table_name
self.name.tableize
end
end
end
class Foo < Tableless; end
Foo.table_name # will return "foos"
Это дает вам имя поддельной таблицы, если оно вам понадобится. Без этого метода Foo::table_name
будет оцениваться как "без таблиц".
Ответ 5
Я нашел эту ссылку, которая работает КРАСИВО.
http://codetunes.com/2008/07/20/tableless-models-in-rails/
Ответ 6
Просто добавление к принятому ответу:
Сделайте ваши подклассы наследуемыми родительскими столбцами:
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
Ответ 7
Это форма поиска, которая представляет объект, называемый критерием, который имеет объект вложенного периода с начальными и конечными атрибутами.
Действие в контроллере действительно просто, но оно загружает значения из вложенных объектов в форму и повторно отображает те же значения с сообщениями об ошибках, если это необходимо.
Работает на Rails 3.1.
Модель:
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
В контроллере:
def search
@criteria = Criteria.new params[:criteria]
end
В помощнике:
def criteria_index_path ct, options = {}
url_for :action => :search
end
В представлении:
<%= 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 %>
Производит 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">
Примечание: атрибут действия, предоставляемый хелпером, и формат именования вложенных атрибутов, что делает его настолько простым, чтобы контроллер мог сразу загрузить все значения
Ответ 8
Существует драгоценный камень activerecord-tableless. Это драгоценный камень для создания неактивных моделей ActiveRecord, поэтому он поддерживает проверки, ассоциации, типы. Он поддерживает Active Record 2.3, 3.0, 3.2
Рекомендуемый способ сделать это в Rails 3.x(с использованием ActiveModel) не поддерживает ассоциации и типы.