Модель Rails без базы данных - PullRequest
63 голосов
/ 25 ноября 2008

Я хочу создать модель Rails (2.1 и 2.2) с валидациями ActiveRecord, но без таблицы базы данных. Какой подход наиболее широко используется? Я нашел несколько плагинов, которые утверждают, что предлагают эту функциональность, но многие из них, похоже, не используются и не используются. Что сообщество рекомендует мне сделать? Сейчас я склоняюсь к тому, чтобы придумать собственное решение, основанное на этом блоге .

Ответы [ 13 ]

67 голосов
/ 30 сентября 2010

В Rails 3 есть лучший способ сделать это: http://railscasts.com/episodes/219-active-model

43 голосов
/ 26 ноября 2008

Это подход, который я использовал в прошлом:

В приложение / модели / 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

In app / models / foo.rb

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>>
17 голосов
/ 18 декабря 2015

Теперь есть более простой способ:

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

http://api.rubyonrails.org/classes/ActiveModel/Model.html

8 голосов
/ 25 ноября 2008

Я думаю, что публикация в блоге, на которую вы ссылаетесь, - лучший путь. Я бы только предложил переместить заглушенные методы в модуль, чтобы не загрязнять ваш код.

8 голосов
/ 25 ноября 2008

просто создайте новый файл, оканчивающийся на «.rb», следуя соглашениям, к которым вы привыкли (единственное число для имени файла и имени класса, подчеркнуто для имени файла, регистр верблюда для имени класса) в каталоге «models /». Ключевым моментом здесь является не наследовать вашу модель от ActiveRecord (потому что именно AR дает вам функциональность базы данных). например: для новой модели для автомобилей создайте файл с именем "car.rb" в каталоге моделей / внутри вашей модели:

class Car
    # here goes all your model's stuff
end

edit: btw, если вам нужны атрибуты для вашего класса, вы можете использовать здесь все, что вы используете на 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, возможно, вы найдете это решение лучше;)

5 голосов
/ 30 июня 2017

Ради полноты:

Rails теперь (в V5) имеет удобный модуль, который вы можете включить:

include ActiveModel::Model

Это позволяет вам инициализировать с помощью хеша и использовать проверки среди прочего.

Полная документация здесь .

4 голосов
/ 25 ноября 2008

Есть скринкаст о неактивной модели записи, созданный Райаном Бейтсом. Хорошее место для начала.

На всякий случай, если вы еще не смотрели его.

3 голосов
/ 18 июня 2010

Я сделал быстрый миксин, чтобы справиться с этим, согласно предложению Джона Топли.

http://github.com/willrjmarshall/Tableless

2 голосов
/ 12 мая 2009

Используйте Validatable драгоценный камень. Как вы говорите, есть решения на основе AR, но они, как правило, хрупкие.

http://validatable.rubyforge.org/

2 голосов
/ 25 ноября 2008

А как насчет пометки класса как абстрактного?

class Car < ActiveRecord::Base
  self.abstract = true
end

это сообщит рельсам, что у класса Car нет соответствующей таблицы.

[править]

это действительно не поможет вам, если вам нужно будет сделать что-то вроде:

my_car = Car.new
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...