Почему: readonly => true не работает в ассоциации own_to? - PullRequest
4 голосов
/ 23 июня 2011

У меня есть следующая модель:

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

end

Я ожидаю, что атрибут: readonly => true предотвратит изменение пользователя, т.е.

# assume we've set up user_1, user_2 and question 
# and that question.user == user_1

question.user = user_2
question.save
question.reload 
question.user == user_2 # true - why?

Почему это правда - я ожидал, что: readonly => true предотвратит изменение этого атрибута после первоначального создания? Если это не так, что делает опция: readonly?

EDIT

Использование attr_readonly даст неизменяемость (неизменность?), Которую я искал.

class Question < ActiveRecord::Base

  belongs_to :user
  attr_readonly :user_id

end

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

Ответы [ 3 ]

7 голосов
/ 23 июня 2011

Из документа

:readonly
    If true, the associated object is readonly through the association.

Итак, я полагаю, что это мешает вам делать такие вещи, как

question.user.name = 'Hacked'

Но позвольте вам продолжать изменять само отношение.

0 голосов
/ 16 июля 2014

насколько относится к относится к столбцу id def user = (new_user) не будет запускаться, но def user_id = (new_user_id) подойдет!Таким образом, пример будет:

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

  def user_id=(new_user_id)
    if self.user.nil?
      write_attribute :user_id , new_user_id
    else 
      return false # or raise your preference 
    end
  end
end

Протестировано здесь на Rails4 и ruby ​​1.9.3

0 голосов
/ 23 июня 2011

Как сказал @christianblais, это влияет только на изменение свойств объекта, но не на его замену.

, чтобы предотвратить переопределение user = в вашей модели

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

  def user=(new_user)
    if self.user.nil?
      write_attirbute :user_id , new_user.id
    else 
      return false # or raise your prefrence 
    end
end

или вы можете исключить условное выражение и заставить его всегда вызывать исключение, а затем инициализировать его с новыми или создать, / обновить атрибуты

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