рельсы переопределяют получатель по умолчанию для отношения - PullRequest
46 голосов
/ 23 марта 2010

Итак, я знаю, как переопределить методы получения по умолчанию для атрибутов объекта ActiveRecord, используя

def custom_getter
  return self[:custom_getter] || some_default_value
end

Я пытаюсь достичь того же, однако, для принадлежности к ассоциации. Например.

class Foo < AR
  belongs_to :bar

  def bar
    return self[:bar] || Bar.last
  end
end

class Bar < AR
  has_one :foo
end

Когда я говорю:

f = Foo.last

Я бы хотел, чтобы метод f.bar возвращал последний столбец, а не ноль, если эта связь еще не существует.

Однако это не работает. Причина в том, что self [: bar] всегда неопределено. Это на самом деле самостоятельно [: bar_id].

Я могу сделать что-то наивное, как:

def bar
  if self[:bar_id]
    return Bar.find(self[:bar_id])
  else
    return Bar.last
  end
end

Однако, это всегда будет вызывать дб, даже если Bar уже получен, что, конечно, не идеально.

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

Ответы [ 3 ]

71 голосов
/ 23 марта 2010

alias_method - ваш друг здесь.

alias_method :original_bar, :bar
def bar
  self.original_bar || Bar.last
end

Способ, которым это работает, заключается в том, что вы называете метод "bar" по умолчанию как "original bar", а затем реализуете собственную версию "bar". Если вызов original_bar возвращает nil, вместо этого вы возвращаете последний экземпляр Bar.

19 голосов
/ 21 февраля 2016

я обнаружил, что использование "супер" - лучший способ

def bar
  super || Bar.last
end

Надеюсь, это поможет вам: D

10 голосов
/ 09 марта 2013

Ответ Рэнди точен, но есть более простой способ написать его, используя alias_method_chain:


def bar_with_default_find
  self.bar_without_default_find || Bar.last
end
alias_method_chain :bar, :default_find

Это создает два метода - bar_with_default_find и bar_without_default_find и псевдонимы bar для with метода. Таким образом, вы можете явно вызвать один или другой, или просто оставить значения по умолчанию.

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