Rails 3:模型中的哈希访问器?

时间:2010-12-01 19:39:25

标签: ruby-on-rails

除了我已经完成的教程示例之外,我正在努力扩展我对一些基本Rails概念的理解。我找不到任何Q& A / docs / walkthroughs正在做我想做的事情,所以我很有可能以错误的方式解决这个问题。

我有一个包含许多标签的Team对象。 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 个答案:

答案 0 :(得分:5)

可能有不同的方法来做同样的事情。您可以定义匿名关联扩展,并为其定义数组访问器方法,以便使用键检索标记。

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

这样,您只需从数据库中获取所需的标记,而不是一次性获取它们只是为了使用其中一个标记。它可以让你这样做:

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