新手问题 acts_as_taggable_on + simple_form + select2 只有最后一个标签被保存 [已解决]

dongli1985 · 2015年08月11日 · 最后由 dongli1985 回复于 2015年08月12日 · 3116 次阅读

我使用acts_as_taggable_on做标签,和simple_form+select2做标签的输入。表单的代码片段为:

<%=
  f.input :category_list,
  label: false,
  collection: @article.categories.map { |t| t.name }
%>

select2调用如下:

$('#article_category_list').select2
  tags: true
  multiple: true

在输入时显示有两个标签: 当保存按钮被点击时,打印select元素的值: 保存后却只显示最后一个标签:

请问该如何解决呢?

更新 1: 忘记贴相关日志了:

Started PATCH "/users/1/articles/1" for 127.0.0.1 at 2015-08-11 22:55:17 +0800
Processing by ArticlesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"BlU5N1JObvkG6dhL0r98p1ejms0CmdifwFF9FZYuO5/bvsCNNTonhhldhFro94kKqn0KleOjN3VqB9kvWF20pg==", "article"=>{"user_id"=>"1", "title"=>"云滴谱的数值求解", "category_list"=>"第二个标签", "privacy"=>"0", "group_ids"=>[""], "content"=>"\\\\[ \\frac{\\partial n}{\\partial t} = - \\frac{\\partial}{\\partial r} \\frac{d r}{d t} n \\\\]"}, "commit"=>"修改", "user_id"=>"1", "id"=>"1"}

可见category_list中只有第二个标签

更新 2: 我将表单输入改为如下形式有效果:

<%=
  f.text_field :category_list,
  label: false
%>
Started PATCH "/users/1/articles/1" for 127.0.0.1 at 2015-08-12 08:01:01 +0800
Processing by ArticlesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"RCYsujn6X6taCRUqJLUUUITQOY1HmrJ9DVyz6HtylUA7GFwD/XoHU1MSuDiNrLDO8u+TjooSssmqy3GFuvKdOQ==", "article"=>{"user_id"=>"1", "title"=>"云滴谱的数值求解", "category_list"=>"第二个标记,第三个标记", "privacy"=>"0", "group_ids"=>[""], "content"=>"\\\\[ \\frac{\\partial n}{\\partial t} = - \\frac{\\partial}{\\partial r} \\frac{d r}{d t} n \\\\]"}, "commit"=>"修改", "user_id"=>"1", "id"=>"1"}

但是表单输入没有select2那样的分块: 最接近的一个例子在这里,但是该方法似乎不管用了。

更新 3(最终版):

经过折腾(debugger),终于大概搞清楚问题所在。首先说在更新 2 中,使用了text_field,此时从表单传回的category_list是一个字符串,所以在强参数处无需说明category_list是一个数组,方法有效,但是输入时没有select2那种分块的好看,因此废弃。在最开始的方法中,使用了select元素,传回的是数组,因此需要说明category_list是一个数组:

params.require(:article).permit(..., { category_list: [] }, ...)

其次还需要在表单中显式支持multiple: 'multiple'(正如@_kaichen支持的,但是写multiple: true无效):

<%=
  f.input :category_list,
  label: false,
  collection: @article.categories.map { |t| t.name },
  include_blank: false,
  input_html: {
    multiple: 'multiple'     # <---------- 这个一定要加
  }
%>

否则就只会传回最后一个标签了。问题最终看来很简单,但是对于新手一开始还是有点摸不着头脑。

非常感谢各位的帮助!

看一下后台 log 输出的画面传参部分是否两个都传回来了,把那段 log 信息给出来的话更能让大家帮你分析

#1 楼 @ywjno 十分感谢回复!忘记把 log 贴出来了,见更新。

f.input 里要把 multiple: true 传进去。

不然构造出来的参数就是 category_list 而不是正确的 category_list[] ,如 Log 所示 Rails 会将它处理为 "category_list"=>"第二条评论"

3 楼正解,或者可以试试<%= f.input "category_list[]",应该也可以

@_kaichen 我在f.input里加上了multiple: true,没有效果。

@leomayleomay 我又将:category_list换为category_list[],结果提示:

undefined method `category_list[]' for #<Article:0x007f918f5cac60>

加上 multiple: true 之后应该还要改这里吧

params.require(:article).permit(:title, :content, category_list: [])

#6 楼 @greatghoul 文档中显示不用,我也试了一下,没有效果呢。

更新:你的提示很重要,是正确的,但是我还需要更改其它地方,在帖子中的更新 3 指出。十分感谢!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号