【问题标题】:How do I elegantly combine these two ruby commands?如何优雅地结合这两个 ruby​​ 命令?
【发布时间】:2013-11-25 07:45:40
【问题描述】:

我在我的Item 模型上使用ActsAsTaggableOn

要获得带有特定标签的所有项目的列表,我必须这样做:

Item.tagged_with("some_tag")

但是,我在导航部分中使用它来根据标签中的项目数量动态生成标签导航。我想要项目数量最多的 4 个标签。

所以我在我的navigation partial 中这样做:

<% Item.tag_counts.order(:count).limit(4).each do |tag| %>
    <% if params[:tag] == tag.name %>
        <li class="active"><%= link_to tag.name.capitalize, tag_path(tag.name) %></li>
    <% else %>
        <li><%= link_to tag.name.capitalize, tag_path(tag.name) %></li>
    <% end %>
<% end %>

但是,当我只有 2 或 3 件商品(即任何低于 4 但大于 1 的数量)并且我有一件商品已被标记但未“批准”时(即它不会显示在页面上,直到它已被管理员批准并且标志is_approvedfalse 更改为truetag 显示在此列表中(这很糟糕,我不希望它在没有项目时出现已被批准),但是当您单击标签时该项目不会显示(这很好,因为它尚未被批准)。

如何修改each 语句以同时容纳items 已经是approved

确定Item 是否已获批准的最简单方法如下:

item.is_approved?

例子:

> i
 => #<Item id: 17, name: "10pp-logo", link: "10pound.zip", description: "10PP Logo.<br><br>Full of graphical good...", price: 6.99, user_id: 1702, created_at: "2013-11-24 12:56:05", updated_at: "2013-11-24 12:56:05", image: "ten.png", is_approved: false, approved_at: nil> 
> i.is_approved?
 => false 

编辑 1:

 > Item.tag_counts
   (2.0ms)  SELECT items.id FROM "items" 
  ActsAsTaggableOn::Tag Load (4.5ms)  SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN items ON items.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Item' AND taggings.context = 'tags') AND (taggings.taggable_id IN(13,15,17)) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id
 => [#<ActsAsTaggableOn::Tag id: 6, name: "gmail">, #<ActsAsTaggableOn::Tag id: 11, name: "10pp">, #<ActsAsTaggableOn::Tag id: 4, name: "twitter">, #<ActsAsTaggableOn::Tag id: 5, name: "facebook">, #<ActsAsTaggableOn::Tag id: 8, name: "fitness">, #<ActsAsTaggableOn::Tag id: 1, name: "notepad">, #<ActsAsTaggableOn::Tag id: 2, name: "paper">, #<ActsAsTaggableOn::Tag id: 9, name: "logo">, #<ActsAsTaggableOn::Tag id: 7, name: "login form">] 

【问题讨论】:

  • 方法.tag_counts返回什么?类似 [[tag_name, count][...]] 的数组?
  • @tyler - 是一个数组。
  • 什么数组?它的实际结构是什么?
  • @tyler 更新了问题给你看。

标签: ruby-on-rails ruby ruby-on-rails-3 acts-as-taggable-on


【解决方案1】:

为什么不只列出批准的项目?

class Item < ActiveRecord::Base
  def self.approved_and_tagged_with(tags)
    self.tagged_with(tags).where(approved: true)
  end
end

# View
Item.approved_and_tagged_with("some_tag")

更新:包装标记最多的项目

class Item < ActiveRecord::Base
  scope :approved, where(approved: true)

  # @param: options. allow nil
  #   example: most_tagged(limit: 10, require_approval: false)
  def self.most_tagged(options={})
    limit = options[:limit] || 4
    require_approval = options[:require_approval] || true
    results = tag_counts.order(:count).limit(limit)
    results = results.approved if require_approval?
    results
  end
end

# View
Items.most_tagged.each do |item|
  # blah blah
end

【讨论】:

  • 问题是我不只调用 1 个标签。我认为你在正确的轨道上,但我的navigation 并没有那样工作。我想修改迭代器,我正在用导航部分的完整代码更新问题。
  • 无论你想要多少标签或你需要做的任何其他花哨的事情都没有关系。只要你需要打db,你可以在里面组合批准的逻辑,通过包装act_as_taggable_on方法。
  • 理想情况下,我希望能够在遍历tag_count 上的所有标签时,只查看标签where(is_approved: true)
  • 您能否更新您的答案以反映您的建议和我的实际代码。谢谢。
  • 很好...出于好奇...你为什么要加入options.require_approval || true
猜你喜欢
  • 2020-06-16
  • 2021-08-07
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2021-11-30
  • 2011-12-01
  • 2021-09-21
相关资源
最近更新 更多