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. 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.
I have a Team object with many Tags. The Team table has a few normalized fields, but most of the characteristics of the team are stored as Tags, i.e the Team 'Virginia Cavaliers' has Tags
{[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.
cla开发者_如何学运维ss 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:
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"] %>
精彩评论