Рельсы модель без базы данных
Я хочу создать модель Rails (2.1 и 2.2) с проверками ActiveRecord, но без таблицы базы данных. Каков наиболее широко используемый подход? Я нашел некоторые плагины, которые утверждают, что предлагают эту функциональность, но многие из них, похоже, не широко используются или поддерживаются. Что сообщество рекомендует мне делать? Прямо сейчас я склоняюсь к тому, чтобы придумать свое собственное решение, основанное на этот блог.
13 ответов:
Я думаю, что в блоге вы связываете это лучший способ пойти. Я бы только предложил переместить заглушенные методы в модуль, чтобы не загрязнять ваш код.
есть лучший способ сделать это в Rails 3:http://railscasts.com/episodes/219-active-model
это подход, который я использовал в прошлом:
на приложение / модели / без таблиц.РБ
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
на приложение / модели / foo.РБ
class Foo < Tableless column :bar, :string validates_presence_of :bar end
на скрипт/консоли
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>>
теперь есть более простой способ:
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
просто создайте новый файл с окончанием ".rb " после соглашений, к которым вы привыкли (единственное число для имени файла и имени класса, подчеркнуто для имени файла, случай верблюда для имени класса) в вашем каталоге "модели/". Ключ здесь-не наследовать вашу модель от ActiveRecord (потому что именно AR дает вам функциональность базы данных). например: для новой модели для автомобилей, создайте файл под названием "автомобиль.РБ" в вашей модели/ каталог и внутри вашей модели:
class Car # here goes all your model's stuff end
правка: кстати, если вы хотите атрибуты вашего класса, вы можете использовать здесь все, что вы используете на ruby, просто добавьте пару строк с помощью "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's stuff end
edit #2: после прочтения комментария Майка, я бы сказал вам идти своим путем, если вы хотите, чтобы все функции ActiveRecord, но не таблицы в базе данных. Если вы просто хотите обычный класс Ruby, возможно, вы найдете это решение лучше ;)
здесь видеоуроки о неактивной модели записи, составленной Райаном Бейтсом. Хорошее место для начала.
на всякий случай, если вы еще не смотрели его.
для полноты картины:
Rails now (at V5) имеет удобный модуль, который вы можете включить:
include ActiveModel::Model
Это позволяет инициализировать с помощью хэша и использовать проверки среди прочего.
полная документация здесь.
Как насчет маркировки класса как абстрактного?
class Car < ActiveRecord::Base self.abstract = true end
это скажет рельсы, что класс автомобиля не имеет соответствующей таблицы.
[edit]
это действительно не поможет вам, если вам нужно будет сделать что-то вроде:
my_car = Car.new
используйте проверяемый камень. Как вы говорите, есть решения на основе AR, но они, как правило, хрупкие.
кто-нибудь когда-либо пытался включить
ActiveRecord::Validations
иActiveRecord::Validations::ClassMethods
в неактивный класс записи и посмотреть, что происходит при попытке установить валидаторы ?Я уверен, что существует множество зависимостей между платформой проверки и самим ActiveRecord. Но вы можете успешно избавиться от этих зависимостей, разветвив свою собственную структуру проверки из структуры проверки AR.
просто идея.
обновление: Oops, это больше или меньше того, что предлагается в сообщении, связанном с вашим вопросом. Извините за беспокойство.
сделайте, как сказал Тиаго Пинто, и просто не наследуйте свою модель от ActiveRecord::Base. Это будет просто обычный класс Ruby, который вы вставляете в файл в своем каталоге app/models/. Если ни одна из ваших моделей не имеет таблиц, и вы вообще не используете базу данных или ActiveRecord в своем приложении, обязательно измените свою среду.rb файл должен иметь следующую строку:
config.frameworks -= [:active_record]
Это должно быть в пределах
Rails::Initializer.run do |config|
блок.
вы должны проверить PassiveRecord плагин. Это дает вам ActiveRecord-подобный интерфейс для моделей без базы данных. Это просто, и меньше хлопот, чем борьба с ActiveRecord.
мы используем PassiveRecord в сочетании с Validatable драгоценный камень, чтобы получить желаемое поведение ОП.