我正在为Rails应用程序使用act-as-taggable-on,每次我创建一个新的Photo(例如)时,我都会在'标记中获得重复的行。表
我的模型类看起来像:
class User < ActiveRecord::Base
acts_as_tagger
...
end
和
class Photo < ActiveRecord::Base
acts_as_taggable_on :tags
...
end
和我的photos_controller的创建动作
def create
@user = current_user
...
@user.tag(@photo, :with => params[:photo][:tag_list], :on => :tags)
...
end
奇怪的是,我在&#39;标记中获得了重复的行。表格第一行有&#39; tagger_id&#39;和&#39; tagger_type&#39;设置为NULL,而重复行具有正确的值。
我的Gemfile看起来像这样
gem 'rails', '3.2.8'
gem 'acts-as-taggable-on', '~> 2.3.1'
之前有没有人见过这种行为?这是我的配置问题吗?
更新: 看着控制台,我可以清楚地看到正在执行的两个事务,在第一个事务中就是这样:
SQL (0.6ms) INSERT INTO "taggings" ("context", "created_at", "tag_id",
"taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ?, ?, ?)
[["context", "tags"], ["created_at", Thu, 27 Sep 2012 21:49:22 UTC +00:00], ["tag_id",
12], ["taggable_id", 10], ["taggable_type", "Photo"],
["tagger_id", nil], ["tagger_type", nil]]
很明显tagger_id设置为null以及tagger_type。
这是一个完整的控制台输出,我将这些行分开以帮助阅读它。您将注意到两个单独的事务,在第一个事务中,插入时带有NULL值,而在第二个事务结束时,您将看到正确的事务。
开始发布&#34; / photo&#34;在2012-09-28 07:39:58 +0200的127.0.0.1 由PhotoController处理#create as HTML 参数:{&#34; utf8&#34; =&gt;&#34;✓&#34;,&#34; authenticity_token&#34; =&gt;&#34; IOmnfDpU7V7vYw3h6RXXzXPsXf / B0fcVihXhb + S8JHU =&#34;, &#34;照片&#34; =&gt; {&#34; url&#34; =&gt;&#34; www.another.com/photo.jpg",&#34; title&#34; =&gt; ;&#34;另一个&#34;,&#34; tag_list&#34; =&gt;&#34; a_tag&#34;,&#34;说明&#34; =&gt;&#34;&#34;, &#34;私人&#34; =&gt;&#34; 0&#34;},&#34;提交&#34; =&gt;&#34;添加照片&#34;} 重定向到http://www.somedomain.com:3000/users/christiangiacomi
完成302发现在414ms(ActiveRecord:20.5ms)
用户负载(0.3ms)SELECT&#34;用户&#34;。* FROM&#34;用户&#34;用户&#34;。&#34;用户名&#34; =&#39; christiangiacomi&#39;限制1 ActsAsTaggableOn :: Tag Load(0.2ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; INNER JOIN&#34;标签&#34; ON&#34;标签&#34;。&#34; id&#34; =&#34;标记&#34;。&#34; tag_id&#34;标签&#34;。&#34; taggable_id&#34; IS NULL和&#34;标记&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND(taggings.context =&#39; tags&#39; AND taggings.tagger_id IS NULL)
(0.1ms)开始交易
SQL(6.2ms)INSERT INTO&#34; photos&#34; (&#34; created_at&#34;,&#34;说明&#34;,&#34;收藏&#34;,&#34;私人&#34;,&#34;标题&#34;,&#34; updated_at&#34;,&#34; url&#34;,&#34; user_id&#34;)VALUES(?,?,?,?,?,?,?,?)[[&#34; created_at&#34 ;,星期五,2012年9月28日05:39:59 UTC +00:00],[&#34;描述&#34;,&#34;&#34;],[&#34;最爱&#34;,false ],[&#34;私人&#34;,假],[&#34;标题&#34;,&#34;另一个&#34;],[&#34; updated_at&#34;,星期五,2012年9月28日05:39:59 UTC +00:00],[&#34; url&#34;,&#34; http://www.another.com/photo.jpg"],[&#34; user_id& #34;,1]]
ActsAsTaggableOn :: Tag Load(3.2ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; WHERE(lower(name)=&#39; a_tag&#39;) ActsAsTaggableOn ::标签存在(0.1ms)SELECT 1 AS一个FROM&#34;标签&#34;在哪里&#34;标签&#34;。&#34;名称&#34; =&#39; a_tag&#39;限制1
SQL(0.2ms)INSERT INTO&#34;标签&#34; (&#34;名称&#34;)价值观(?)[[&#34;名称&#34;,&#34; a_tag&#34;]]
ActsAsTaggableOn :: Tag Load(0.1ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; INNER JOIN&#34;标签&#34; ON&#34;标签&#34;。&#34; id&#34; =&#34;标记&#34;。&#34; tag_id&#34;标签&#34;。&#34; taggable_id&#34; = 13 AND&#34;标签&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND(taggings.context =&#39; tags&#39; AND taggings.tagger_id IS NULL)
ActsAsTaggableOn ::标记存在(0.2ms)SELECT 1 AS一个FROM&#34;标记&#34;在哪里(&#34;标签&#34;。&#34; tag_id&#34; = 16 AND&#34;标签&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND& #34;标记&#34;。&#34; taggable_id&#34; = 13 AND&#34;标记&#34;。&#34; context&#34; =&#39;标记&#39; AND&#34; taggings&#34;。&#34; tagger_id&#34; IS NULL AND&#34; taggings&#34;。&#34; tagger_type&#34; IS NULL)LIMIT 1
SQL(0.7ms)INSERT INTO&#34;标记&#34; (&#34; context&#34;,&#34; created_at&#34;,&#34; tag_id&#34;,&#34; taggable_id&#34;,&#34; taggable_type&#34;,&#34; tagger_id&#34;,&#34; tagger_type&#34;)VALUES(?,?,?,?,?,?,?)[[&#34; context&#34;,&#34; tags&#34;] ,[&#34; created_at&#34;,星期五,2012年9月28日05:39:59 UTC +00:00],[&#34; tag_id&#34;,16],[&#34; taggable_id&#34; ,13,[&#34; taggable_type&#34;,&#34; Photo&#34;],[&#34; tagger_id&#34;,nil],[&#34; tagger_type&#34;,nil]]
(4.1ms)提交事务
(0.1ms)开始交易
ActsAsTaggableOn :: Tag Load(0.2ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; WHERE(lower(name)=&#39; a_tag&#39;)
ActsAsTaggableOn :: Tag Load(0.2ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; INNER JOIN&#34;标签&#34; ON&#34;标签&#34;。&#34; id&#34; =&#34;标记&#34;。&#34; tag_id&#34;标签&#34;。&#34; taggable_id&#34; = 13 AND&#34;标签&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND(taggings.context =&#39; tags&#39; AND taggings.tagger_id IS NULL)
CACHE(0.0ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; WHERE(lower(name)=&#39; a_tag&#39;)
ActsAsTaggableOn :: Tag Load(0.2ms)SELECT&#34; tags&#34;。* FROM&#34; tags&#34; INNER JOIN&#34;标签&#34; ON&#34;标签&#34;。&#34; id&#34; =&#34;标记&#34;。&#34; tag_id&#34;标签&#34;。&#34; taggable_id&#34; = 13 AND&#34;标签&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND(taggings.context =&#39;标签&#39; AND taggings.tagger_id = 1 AND taggings.tagger_type =&#39;用户&#39;)
ActsAsTaggableOn ::标记存在(0.4ms)SELECT 1 AS一个FROM&#34;标记&#34;在哪里(&#34;标签&#34;。&#34; tag_id&#34; = 16 AND&#34;标签&#34;。&#34; taggable_type&#34; =&#39;照片&#39; AND& #34;标记&#34;。&#34; taggable_id&#34; = 13 AND&#34;标记&#34;。&#34; context&#34; =&#39;标记&#39; AND&#34;标签&#34;。&#34; tagger_id&#34; = 1 AND&#34;标记&#34;。&#34; tagger_type&#34; =&#39;用户&#39;)LIMIT 1
SQL(0.5ms)INSERT INTO&#34;标记&#34; (&#34; context&#34;,&#34; created_at&#34;,&#34; tag_id&#34;,&#34; taggable_id&#34;,&#34; taggable_type&#34;,&#34; tagger_id&#34;,&#34; tagger_type&#34;)VALUES(?,?,?,?,?,?,?)[[&#34; context&#34;,&#34; tags&#34;] ,[&#34; created_at&#34;,星期五,2012年9月28日05:39:59 UTC +00:00],[&#34; tag_id&#34;,16],[&#34; taggable_id&#34; ,13,[&#34; taggable_type&#34;,&#34; Photo&#34;],[&#34; tagger_id&#34;,1],[&#34; tagger_type&#34;,&#34 ;用户&#34;]]
(2.4ms)提交事务
答案 0 :(得分:2)
我知道这个问题现在好五年了,但这仍然发生在带有acts-as-taggable 4.0
的Rails 5.1中,我只是想表明如何解决这个问题。
这是一个非常简单的修复方法,在你的控制器强大的参数中你只需要添加tag_list: []
而不是:tag_list
,如下所示:
def photo_params
params.require(:photo).permit(:title, tag_list: [])
end
这会阻止在数据库中创建重复和空白Taggings
,您可以使用form_for
而不是form_tag
<%= form_for @photo do |f| %>
<%= f.text_field :title %>
<%= f.text_field :tag_list %>
<%= f.submit %>
<% end %>
答案 1 :(得分:1)
好的,这真的很奇怪,但我已经想出了如何避免这个问题。
我做的第一件事是创建一个尖峰解决方案来测试acts_as_taggable_on,这似乎有效。它由两个模型类组成,就是它......当我通过rails控制台进行测试时它就起作用了。
所以我添加了一个像我在rails应用程序中的表单并再次测试它......
我的表格是这样的:
<div>
<%= form_for @photo, :html => { :class => "dialog" } do |f| %>
...
<%= f.label :title%>
<%= f.text_field :title, :class => "wide" %>
<%= f.label 'Tags' %>
<%= f.text_field :tag_list, :value => @tags %>
...
<%= f.submit button_text(@photo), :class => "btn btn-large btn-primary" %>
<%= f.submit "Cancel", :class => "btn btn-large" %>
</div>
当我实现这个并测试它时,我得到了一个'无法批量分配:tag_list'
我读到了Rails 3.2.3中关于质量分配的变化,并决定不妥协安全性。
所以我添加到我的Photo模型类
attr_accessible :tag_list
这解决了错误但是当我测试它时我发现现在出现的重复行!所以现在这个bug是可以重现的!!
我通过更改表单解决了这个问题,因此我没有将表单绑定到Photo模型对象。
像这样:
<div>
<%= form_tag({:controller => "photos", :action => "create"}, :method => "post", :class => "dialog") do %>
...
<%= label_tag :title, 'Title'%>
<%= text_field_tag :title, nil, :class => "wide" %>
<%= label_tag :tag_list, 'Tags'%>
<%= text_field_tag :tag_list, nil, :class => "wide" %>
...
<%= submit_tag('Add', :class => "btn btn-large btn-primary") %>
<%= submit_tag("Cancel", :class => "btn btn-large") %>
</div>
我还删除了attr_accessible:tag_list并修改了控制器以接受表单中的不同值。
@photo = current_user.photos.build(:title => params[:title],
...
)
@user.tag(@photo, :with => params[:tag_list], :on => :tags)
这解决了这个问题!
我现在将试着确切了解为什么会发生这种情况! :)