Как создать неактивную модель ActiveRecord в Rails 3
Я пытаюсь создать неактивную модель Active Record. Мой user.rb выглядит следующим образом
class User < ActiveRecord::Base
class_inheritable_accessor :columns
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
column :name, :text
column :exception, :text
serialize :exception
end
При создании нового объекта в контроллере
@user = User.new
Я получаю сообщение об ошибке
Mysql2:: Ошибка: Таблица "Sampledb.users" не существует: SHOW FIELDS FROM users
Ответы
Ответ 1
class Tableless
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
def self.attr_accessor(*vars)
@attributes ||= []
@attributes.concat( vars )
super
end
def self.attributes
@attributes
end
def initialize(attributes={})
attributes && attributes.each do |name, value|
send("#{name}=", value) if respond_to? name.to_sym
end
end
def persisted?
false
end
def self.inspect
"#<#{ self.to_s} #{ self.attributes.collect{ |e| ":#{ e }" }.join(', ') }>"
end
end
Ответ 2
Немного вещей:
Во-первых, вы используете подход Rails2, описанный в Railscast 193, когда вы действительно должны использовать подход Rails 3, описанный в Railscast 219
Вероятно, вы не хотите наследовать от ActiveRecord:: Base при выполнении такого рода вещей.
Прочитайте сообщение Yehuda Katz в блоге.
Ответ 3
Как упоминалось в stephenmurdoch
в rails 3.0 +, вы можете использовать метод, описанный в railscasts 219
Мне пришлось внести небольшую модификацию, чтобы заставить это работать:
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :content
validates_presence_of :name
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_length_of :content, :maximum => 500
def initialize(attributes = {})
unless attributes.nil?
attributes.each do |name, value|
send("#{name}=", value)
end
end
end
def persisted?
false
end
end
Ответ 4
Не наследуйте свой класс от ActiveRecord::Base
.
Если модель наследует от ActiveRecord:: Base, как и следовало ожидать от класса модели, она хочет иметь базовую базу данных.
Ответ 5
Просто удалите:
class_inheritable_accessor :columns
И он должен работать даже с ассоциациями, подобными модели с таблицей.
Ответ 6
Просто для тех, кто все еще борется с этим. Для рельсов 2.x.x
class TestImp < ActiveRecord::Base
def self.columns
@columns ||= []
end
end
Для rails 3.1.x вы можете либо включить ActiveModel (как объяснено с помощью @ducktyped), не наследуя от ActiveRecord, либо если вам нужно наследовать от ActiveRecord:: Base по какой-то причине, то вышесказанное с еще одним дополнением:
class TestImp < ActiveRecord::Base
def attributes_from_column_definition
[]
end
def self.columns
@columns ||= []
end
end
Ответ 7
Для Rails >= 3.2 есть activerecord-tableless драгоценный камень. Это драгоценный камень для создания неактивных моделей ActiveRecord, поэтому он поддерживает проверки, ассоциации, типы.
Когда вы используете рекомендуемый способ сделать это в Rails 3.x, нет поддержки для ассоциации и типов.