简体   繁体   English

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

[英]Rails 3: Hash accessor in the model?

I'm struggling to stretch my understanding of some basic Rails concepts beyond the tutorial examples I've done. 除了我已经完成的教程示例之外,我正在努力扩展我对一些基本Rails概念的理解。 I can't find any Q&A/docs/walkthroughs doing what I'm trying to do, so there's a good chance I'm going about this the wrong way. 我找不到任何Q&A / docs / walkthroughs正在做我想做的事情,所以我很有可能以错误的方式解决这个问题。

I have a Team object with many Tags. 我有一个包含许多标签的Team对象。 The Team table has a few normalized fields, but most of the characteristics of the team are stored as Tags, ie the Team 'Virginia Cavaliers' has Tags Team表有一些标准化字段,但团队的大多数特征都存储为标签,即团队'Virginia Cavaliers'有标签

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

etc. The db design was meant to accommodate many types of teams in the same table, with the tag table facilitating search for teams by arbitrary criteria. 数据库设计旨在容纳同一表中的许多类型的团队,标签表便于按任意标准搜索团队。

So far so good. 到现在为止还挺好。 What I can't figure out is how to best access the team attributes given the team. 我无法弄清楚的是如何最好地访问团队的团队属性。

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    

The hash is there but I can't access it in a view the way I'd like. 哈希就在那里,但我不能按照我喜欢的方式访问它。

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

Is this sensible? 这是明智的吗? possible? 可能? Thanks for your responses. 谢谢你的回复。

* Edited based on feedback (This site is awesome)* *根据反馈编辑(本网站很棒)*

The second suggestion is slick syntacticly, but has two hang ups I can see. 第二个建议是语法上的光滑,但我可以看到两个挂起。 I have to catch nulls as not all teams have all tags and sometimes they show up in the same list: 我必须捕获空值,因为并非所有团队都拥有所有标签,有时它们会出现在同一个列表中:

My clumsy implementation: 我笨拙的实施:

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

The clean code thanks to edgerunner: 感谢edgerunner的干净代码:

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

And if I'm not wrong this method makes extra database calls every time I access a tag. 如果我没有错,这种方法每次访问标签时都会进行额外的数据库调用。 The first method needs just one when the object is instantiated. 在实例化对象时,第一种方法只需要一种方法。 Did I get both of those right? 我是否同时获得了这两项权利?

There may be a different way to do the same. 可能有不同的方法来做同样的事情。 You can define an anonymous association extension and define the array accessor method for that to retrieve the tags with keys. 您可以定义匿名关联扩展,并为其定义数组访问器方法以使用键检索标记。

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

This will let you fetch only the required tags from the database instead of getting them all at once just to use one of them. 这将允许您从数据库中仅获取所需的标记,而不是一次性获取它们只是为了使用其中一个。 It lets you do this: 它可以让你这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM