在我的rails应用中,我有两个模型:Team
和Post
,每个Post
可以有多个标记,每个Team
可以有多个Posts
。在我的团队的节目动作中,我想提供一个select_tag
,用户可以使用该select_tag
为其帖子选择所有已创建标签的一个标签。当用户使用Acts as Taggable On
选择标记时,我只想显示也包含该标记的帖子。我使用HAML
gem。
我目前拥有的是这个(我使用= select_tag "tags", options_from_collection_for_select(@posts, "tags", :tag_list)
):
[row 1] Tag 1
[row 2] Tag 1, Tag 2
[...]
这给我一个看起来像这样的选择:
[row 1] Tag 1
[row 2] Tag 2
[row 3] Tag 3
[...]
我想要的是一个如下所示的选择列表:
select_tag
我还没有使用{{1}}。有可能以某种方式做我想做的事吗?那怎么样?
答案 0 :(得分:2)
这有两个方面:显示正确的标签列表,并按所选标签过滤帖子。
您想要创建一个<select>
元素,该元素仅包含该团队帖子的标签。 options_from_collection_for_select
有3个参数:一个集合,一个获取每个选项值的方法,以及一个获取每个选项名称的方法。因此,您应该将一组标记传递给options_from_collection_for_select
,而不是一组帖子。这组标签不应该是所有标签 - 只是您团队帖子的标签。幸运的是,acts_as_taggable_on
提供了一种方法,可以构建标记云。
所以你要更新你的控制器看起来像这样:
class TeamController < ApplicationController
def show
@team = Team.find params[:id]
@posts = team.posts
@team_tags = team.posts.tag_counts_on(:tags)
end
end
并更新您的观点以改为使用@team_tags
:
= select_tag "tag", options_from_collection_for_select(@team_tags, 'id', 'name')
这应该为您提供一个选择框,其中填充了该团队特有的标签。
现在我们已经获得了正确的标记列表,我们希望能够按标记过滤帖子。 <select>
标记应位于表单中;您可以创建一个处理该表单的新控制器操作,也可以相应地调整show
方法。后者有点棘手,所以我在这里采取了这种方法。让我们更新您的观点,使假设更加清晰:
= form_tag team_path(@team), method: 'get', class: 'tag_form' do
= select_tag "tag", options_from_collection_for_select(@team_tags, 'id', 'name', @tag)
= submit_tag "Filter posts"
如果我们有一个&#39;标签,请更新控制器操作以过滤帖子。参数:
class TeamController < ApplicationController
def show
@team = Team.find params[:id]
@team_tags = team.posts.tag_counts_on(:tags)
if params[:tag]
@tag = Tag.find params[:tag]
@posts = team.posts.tagged_with @tag.name
else
@tag = nil
@posts = team.posts
end
end
end
请注意,我们将所选标记作为实例变量@tag
传入,并在我们的options_from_collection_for_select
中使用该标记,以便在我们选择过滤器时选择正确的标记。
您可以使用一点jQuery和CoffeeScript来隐藏您的提交按钮,并在用户选择新标签时自动进行过滤,这会稍微改善您的用户体验。将其添加到app/assets/javascripts/teams.js.coffee
:
$ ->
$forms = $('.tag_form')
$forms.each (i, el) ->
$('input[type=submit]', el).hide()
$('select', el).on 'change', (ev) ->
$(el).submit()
这可以通过查找类tag_form
的所有元素,删除每个元素中的所有<input type="submit">
元素,然后在这些表单中的select元素上侦听change events。