Я хочу создать модель Rails (2.1 и 2.2) с проверками ActiveRecord, но без таблицы базы данных. Каков наиболее широко используемый подход? Я нашел некоторые плагины, которые утверждают, что предлагают эту функциональность, но многие из них, похоже, широко не используются или не поддерживаются. Что рекомендует сообщество? Прямо сейчас я склоняюсь к тому, чтобы придумать свое решение, основанное на этом сообщении в блоге.
Модель Rails без базы данных
Ответ 1
Я думаю, что сообщение в блоге, которое вы связываете, - лучший способ пойти. Я бы предложил только переместить запущенные методы в модуль, чтобы не загрязнять ваш код.
Ответ 2
В Rails 3 есть лучший способ: http://railscasts.com/episodes/219-active-model
Ответ 3
Это подход, который я использовал в прошлом:
В приложении /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>>
Ответ 4
Теперь проще:
class Model
include ActiveModel::Model
attr_accessor :var
validates :var, presence: true
end
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
Ответ 5
просто создайте новый файл, заканчивающийся на ".rb", следуя соглашениям, к которым вы привыкли (единственное значение для имени файла и имени класса, подчеркнутого для имени файла, верблюжьего случая для имени класса) в вашем каталоге "models/". Ключ здесь состоит в том, чтобы не наследовать вашу модель от ActiveRecord (потому что это AR, которая дает вам функциональность базы данных). например: для новой модели для автомобилей, создайте файл под названием "car.rb" в каталоге моделей и внутри вашей модели:
class Car
# here goes all your model stuff
end
edit: btw, если вам нужны атрибуты в вашем классе, вы можете использовать здесь все, что вы используете на рубине, просто добавьте пару строк, используя "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 stuff
end
edit # 2: после прочтения комментария Майка, я бы сказал вам пойти своим путем, если вы хотите использовать все функции ActiveRecord, но нет таблицы в базе данных. Если вы просто хотите обычный класс Ruby, возможно, вы найдете это решение лучше;)
Ответ 6
Там screencast о неактивной образцовой модели, составленной Райаном Бейтсом. Хорошее место для начала.
На всякий случай вы еще не видели его.
Ответ 7
Я построил быстрый Mixin для обработки этого, согласно предложению Джона Топли.
Ответ 8
Как насчет маркировки класса как абстрактного?
class Car < ActiveRecord::Base
self.abstract = true
end
это скажет рельсы, что класс Car не имеет соответствующей таблицы.
[править]
это не поможет вам, если вам нужно сделать что-то вроде:
my_car = Car.new
Ответ 9
Используйте драгоценный камень, который можно использовать. Как вы говорите, есть решения на основе AR, но они имеют тенденцию быть хрупкими.
Ответ 10
Для полноты:
В Rails теперь (на V5) есть удобный модуль, который вы можете включить:
include ActiveModel::Model
Это позволяет вам инициализировать хэш и использовать проверки среди других вещей.
Полная документация здесь.
Ответ 11
Кто-нибудь когда-либо пытался включить ActiveRecord::Validations
и ActiveRecord::Validations::ClassMethods
в класс неактивной записи и посмотреть, что происходит при попытке настроить валидаторы?
Я уверен, что существует множество зависимостей между картой проверки подлинности и самой ActiveRecord. Но вам удастся избавиться от этих зависимостей, разложив свою собственную структуру проверки из структуры проверки подлинности AR.
Просто идея.
Обновить: oopps, это более или менее то, что было предложено в сообщении, связанном с вашим вопросом. Извините за нарушение.
Ответ 12
Сделайте так, как сказал Тьягу Пинто, и у вас нет модели, наследуемой от ActiveRecord:: Base. Это будет обычный рубиновый класс, который вы вставляете в файл в вашем каталоге app/models/. Если ни одна из ваших моделей не имеет таблиц, и вы вообще не используете базу данных или ActiveRecord в своем приложении, обязательно измените файл environment.rb, чтобы иметь следующую строку:
config.frameworks -= [:active_record]
Это должно быть в блоке Rails::Initializer.run do |config|
.
Ответ 13
Вы должны проверить плагин PassiveRecord. Он предоставляет интерфейс ActiveRecord для моделей без базы данных. Это просто, и меньше хлопот, чем борьба с ActiveRecord.
Мы используем PassiveRecord в сочетании с Validatable gem, чтобы получить желаемое поведение OP.