这有效吗?

时间:2011-06-23 20:17:04

标签: ruby-on-rails

你能否告诉我是否有更好的方法。

型号:

class Skill
  has_many :tags
  has_many :positions
end


class Tag
  belongs_to :skill
  has_and_belongs_to_many :positions
end


class Position
  belongs_to :skill
  has_and_belongs_to_many :tags
end

我想列出所有技能和职位的标签。像这样:

skill - tag tag tag tag
skill - tag tag
...

我设法像这样实现了它:

<% @skills.each do |skill| %>
  <%= skill.name %>   
  <% skill.positions.collect{|p| p.tags}.flatten.uniq.each do |t| %>
    <%= t.name %>
  <% end %>   
<% end %>

我的skill_controller:

def index
  @skills = Skill.all
end

这是正确的方法吗?

2 个答案:

答案 0 :(得分:1)

由于标记是一个非常常见的问题,我建议您查看acts-as-taggable-on,这是一个广泛使用且非常好的宝石,可以为任何Rails模型添加标记。

无论如何,你的模型看起来很不错(除了has_and_belongs_to_many经常避免使用has_many :through),但我确实看到了改进的空间:

<% skill.positions.collect{|p| p.tags}.flatten.uniq.each do |t| %>
  <%= t.name %>
<% end %>  

首先,这是您的观点中的许多业务逻辑。您应该在控制器中执行此操作。其次,以相反的方式做到这一点会更有效率:

@tags = Tag.all :conditions => [ "tag.id IN (?)", skill.positions.map &:id ]

还有更有效的方法可以做到这一点,但这应该给你一个想法。

答案 1 :(得分:0)

首先 - 对于任何性能问题,您应该衡量性能。在rake任务中创建所需数量的技能,标签和位置的两倍。然后测量页面加载时间。如果它们能满足您的需求,那就很酷。否则,继续阅读。

这不是特别有效,因为您将通过网络访问数据库以获得每个技能的位置映射,然后再针对每个位置标记映射。您可以使用includes方法使用较少的查询加载 - 请参阅the Rails guide on querying