Rails 3: хеш-аксессор в модели? - PullRequest
       3

Rails 3: хеш-аксессор в модели?

4 голосов
/ 01 декабря 2010

Я изо всех сил пытаюсь расширить свое понимание некоторых базовых концепций Rails за пределы обучающих примеров, которые я сделал. Я не могу найти Q & A / docs / walkthroughs, которые делают то, что я пытаюсь сделать, поэтому есть хороший шанс, что я поступлю неправильно.

У меня есть объект команды со многими тегами. Таблица Team имеет несколько нормализованных полей, но большинство характеристик команды хранятся в виде тегов, т. Е. Команда 'Virginia Cavaliers' имеет теги

{[tag_name => 'Conference', tag_value => 'ACC'],
[tag_name => 'Division', tag_value =>'I']}

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

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

class Team < ActiveRecord::Base
  belongs_to :sport
  has_many :team_subscriptions
  has_many :users, :through => :team_subscriptions
  has_many :tags
  def tagvalue
    #Set up a hash to retrieve tag value by name?
    @tagvalue = {}
    tags.each do |t|
      @tagvalue[t.tag_name] = t.tag_value
    end
    Rails.logger.info(@tagvalues.keys)
  end
end    

Хеш есть, но я не могу получить к нему доступ так, как мне хотелось бы.

<%= @team.tagvalue["Conference"] %>

Это разумно? возможный? Спасибо за ваши ответы.

* Отредактировано на основе обратной связи (Этот сайт потрясающий) *

Второе предложение является синтаксическим, но в нем есть два зависания, которые я вижу. Я должен ловить нули, так как не все команды имеют все теги, и иногда они появляются в одном и том же списке:

Моя неуклюжая реализация:

has_many :tags do 
  def [](key)
    set = where(:tag_name => key)
    if set.length > 0
      set.first[:tag_value]
    end
    nil
  end
end

Чистый код благодаря edgerunner:

has_many :tags do 
  def [](key)
    where(:tag_name => key).first.try(:tag_value)
  end
end

И если я не ошибаюсь, этот метод делает дополнительные вызовы базы данных каждый раз, когда я получаю доступ к тегу. Первый метод нужен только один, когда объект создается. Я правильно понял оба?

1 Ответ

5 голосов
/ 01 декабря 2010

Может быть другой способ сделать то же самое.Вы можете определить расширение анонимной ассоциации и определить метод доступа к массиву для этого, чтобы получить теги с ключами.

class Team < ActiveRecord::Base
  ...
  has_many :tags do 
    def [](key)
      where(:tag_name => key).first.try(:tag_value)
    end
  end
  ...
end

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

<%= @team.tags["Conference"] %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...