Коллекции ActiveRecord и пользовательские методы - PullRequest
2 голосов
/ 09 февраля 2011

Я пытаюсь создать метод класса factory_build для создания объектов Redirect в коллекции ActiveRecord (см. Ниже).

Например @website.redirects.factory_build (: code => 301) вернет новый экземпляр объекта PermenantRedirect.Однако, несмотря на то, что я могу вызвать метод класса factory_build, я не могу получить доступ к primary_key для @website.Есть ли способ получить доступ к @ website.id из коллекции, или я вынужден передать его в вызов метода?Любые другие предложения также будут приветствоваться, может быть, я не собираюсь об этом в правильном подходе.спасибо.

class Website < ActiveRecord::Base
  has_many :redirects
  has_many :permenant_redirects
  has_many :temporary_redirects
end

# Redirect is an abstract class it uses Rails Single Table Inheritance
class Redirect < ActiveRecord::Base
  def self.factory_build(attributes)
    status_code = attributes.delete(:code)
    case status_code
      when 301
        Website.find( ... ).permenant_redirects.new(attributes)
      when 302
        Website.find( ... ).temporary_redirects.new(attributes)
      else
        raise InvalidStatusCodeError
    end
  end
end

class TemporaryRedirect < Redirect
  def status
    302
  end
end

class PermenantRedirect < Redirect
  def status
    301
  end
end

1 Ответ

0 голосов
/ 09 февраля 2011

Вам необходимо получить доступ к области для этого отношения, чтобы иметь возможность правильно построить эти объекты. Это доступно для метода класса:

class Redirect < ActiveRecord::Base
  def self.factory_build(attributes)
    redirect_type =
      case (status_code = attributes.delete(:code))
      when 301
        PermanentRedirect
      when 302
        TemporaryRedirect
      else
        Redirect
      end

    redirect_type.new(attributes.merge(scoped.scope_for_create))
  end
end

Я позволил себе высушить ваш код создания, потому что у вас было много дублирования. Также обратите внимание, что вызов find только для осуществления отношений является пустой тратой ресурсов. Если вам известен идентификатор записи, просто передайте его как атрибут, если только у вас нет веских причин для его извлечения в первую очередь.

Вызов scoped.scope_for_create возвращает атрибуты, определенные вашей текущей областью или областями действия. Обычно они имеют вид чего-то вроде { 'website_id' => 101 } и могут быть переданы вашему вызову create.

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