Когда использовать виртуальный атрибут или передавать данные в хэш в Rails 3 - PullRequest
4 голосов
/ 24 июня 2011

В моем приложении у меня есть модель Widget, модель Feature с ассоциацией has_many - по таблице WidgetFeature.

В соответствии с требованиями, когда я отправляю объект WidgetFeature, я должен добавить к нему также имя_компонента для данной связанной функции.
Существует два способа сделать это:

  1. При отправке объекта сделайте следующее:
widget_feature_object[:feature_name] = feature_name_value

, и тогда я смогу получить к нему доступ в моем контроллере или представлении с помощью widget_feature_object[:feature_name], потому чтоВ объекте есть пары (ключ, значение), поэтому я могу добавить еще один.

2.Сделайте feature_name Виртуальный атрибут в WidgetFeature модели, а затем создайте методы получения и установки для него.

Из того, что я знаю, вам следует использовать виртуальные атрибуты, когда вы хотите создать другое представление, отличное от полей, фактически присутствующих в модели (например, Полное имя = Имя + Фамилия).
здесь тоже самое?

Также , делает ли Rails некоторое кэширование на объектах, которое может пригодиться при использовании виртуальных атрибутов, а не при первом подходе?

Каковы плюсы и минусы каждого подхода и какой из них подходит лучше всего в соответствии с моими требованиями?Большое спасибо.

Ответы [ 3 ]

5 голосов
/ 05 июля 2011

Я бы предложил альтернативный подход: используйте delegate ( документация ).

В WidgetFeature я бы написал:

class WidgetFeature

  belongs_to :feature

  delegate :name, :to => :feature, :prefix => true
end

тогда высмогу написать

f = WidgetFeature.first

f.feature_name #will return f.feature.name

Надеюсь, это поможет.

2 голосов
/ 03 июля 2011

Используйте attr_accessor, когда вы хотите установить метод. В противном случае просто используйте общие функции.

Если вы хотите кешировать, посмотрите памятка

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

Я не уверен, почему вы настаиваете на использовании нотации [] для доступа к вашим атрибутам, но есть один путь, по которому следует следовать:

def [](attr)
  if attr == :feature
    feature    # Return the associated feature object
  else
    super      # Call ActiveRecord::Base#[]
  end
end

Конечно, вы можете добавить немного метапрограммирования для автоматического обнаружения действительных ассоциаций.

Лично мне не очень нравятся обезьяньи патчи таким образом, но, поскольку [] это простой метод, вы, вероятно, в безопасности. Плюс в том, что это позволяет вам widget_feature [: feature] [: name] и даже widget_feature [: feature] [: name] =

Вы получаете все функциональные возможности ActiveRecord, которые вы получаете при вызове widget_feature.feature.

...