Когда использовать себя в модели?
вопрос: когда мне нужно использовать себя в моих моделях в рельсах?
у меня есть set
метод в одной из моих моделей.
class SomeData < ActiveRecord::Base
def set_active_flag(val)
self.active_flag = val
self.save!
end
end
когда я делаю это, все работает нормально. Однако, когда я делаю это:
class SomeData < ActiveRecord::Base
def set_active_flag(val)
active_flag = val
save!
end
end
значение active_flag не изменяется, а происходит сбой молча. Может кто-нибудь объяснить?
Я не могу найти никаких дубликатов, но если кто-то найдет один, это тоже хорошо.
4 ответа:
когда вы выполняете действие над экземпляром, вызывающим метод, вы используете self.
этот код
class SocialData < ActiveRecord::Base def set_active_flag(val) active_flag = val save! end end
вы определяете совершенно новую локальную переменную с областью действия active_flag, устанавливая ее в переданное значение, она ни с чем не связана, поэтому она быстро выбрасывается, когда метод заканчивается, как будто его никогда не существовало.
self.active_flag = val
однако указывает экземпляру изменить свой собственный атрибут active_flag, а не новый переменная. Вот почему это работает.
это происходит из-за обзора. Когда вы находитесь внутри метода и вы попытаетесь set новая переменная, как это:
class SomeData < ActiveRecord::Base def set_active_flag(val) active_flag = val end end
вы создаете совершенно новую переменную, которая живет внутри set_active_flag. Как только это будет выполнено, он уйдет, не изменяя
self.active_flag
(фактическая переменная экземпляра) в любом случае.(это было источником путаницы для меня): когда вы пытаетесь читать экземпляр переменная в ruby, например:
class SomeData < ActiveRecord::Base def whats_my_active_flag puts active_flag end end
вы действительно получите
self.active_flag
(фактическая переменная экземпляра) возвращается.
вот почему:
Ruby сделает все возможное, чтобы избежать возвращения
nil
.
- он изначально спрашивает " делает в рамках
whats_my_active_flag
?- он ищет и понимает, что ответ "нет", так он прыгает до на один уровень, к экземпляру Данных
- он снова спрашивает то же самое: "не
active_flag
существуют в этой области?- ответ "да", и поэтому он говорит:" У меня есть что-то для вас", и он возвращает это!
однако, если вы определяете
active_flag
внутриwhats_my_active_flag
, а затем попросите его, он снова проходит через шаги:
- он спрашивает "Есть ли в рамках
whats_my_active_flag
?- ответ "да", поэтому он возвращает, что значение
в любом случае, это не изменить значение
self.active_flag
Если вы явно не скажете ей об этом.простой способ описать это поведение - "он не хочет вас разочаровывать" и вернуть
nil
-- поэтому он делает все возможное, чтобы найти все, что он может.в то же время, "он не хочет испортить данные, которые вы не собирались изменять", поэтому он не изменяет саму переменную экземпляра.
надеюсь, что это помогает!
Это чтобы убедиться, что вы используете метод setter и не определяете новую переменную. Это деталь использования Ruby и AR, которая часто отключает людей (другое - это (неправильное) использование переменной экземпляра).
обратите внимание, что уже update_attributes! хотя я понимаю желание абстрагироваться.
там же переключить!, что может быть еще лучше, в зависимости от вашего интерфейса к флагу.