2

我在 Rails 应用程序中使用acts-as-taggable-on,每次创建新照片(例如)时,我都会在“标记”表中得到重复的行。

我的模型类看起来像:

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

奇怪的是,我在 'taggings' 表中得到重复的行,其中第一行的 'tagger_id' 和 'tagger_type' 设置为 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 和tagger_type 都设置为null。

这是一个完整的控制台输出,我已将各行分开以帮助阅读它。您会注意到两个单独的事务,在第一个事务中插入了 NULL 值,而在第二个事务结束时,您将看到正确的事务。

在 2012-09-28 07:39:58 +0200 开始 POST "/photo" for 127.0.0.1 由 PhotoController#create 作为 HTML 参数处理:{"utf8"=>"✓", "authenticity_token"=>"IOmnfDpU7V7vYw3h6RXXzXPsXf/ B0fcVihXhb+S8JHU=", "photo"=>{"url"=>"www.another.com/photo.jpg", "title"=>"Another", "tag_list"=>"a_tag", "description" =>"", "private"=>"0"}, "commit"=>"添加照片"} 重定向到http://www.somedomain.com:3000/users/christiangiacomi

完成 302 Found in 414ms (ActiveRecord: 20.5ms)

用户负载 (0.3ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'christiangiacomi' LIMIT 1 ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" INNER在“tags”中加入“taggings”。“id”=“taggings”。“tag_id”其中“taggings”。“taggable_id”为空且“taggings”。“taggable_type”='照片'和(taggings.context = 'tags ' AND taggings.tagger_id 为 NULL)

(0.1ms) 开始交易

SQL (6.2ms) INSERT INTO "photos" ("created_at", "description", "favorite", "private", "title", "updated_at", "url", "user_id") VALUES (?, ?, ? , ?, ?, ?, ?, ?) [["created_at", Fri, 28 Sep 2012 05:39:59 UTC +00:00], ["description", ""], ["favorite", false] , ["private", false], ["title", "Another"], ["updated_at", Fri, 28 Sep 2012 05:39:59 UTC +00:00], ["url", "http:// /www.another.com/photo.jpg"], ["user_id", 1]]

ActsAsTaggableOn::Tag Load (3.2ms) SELECT "tags".* FROM "tags" WHERE (lower(name) = 'a_tag') ActsAsTaggableOn::Tag Exists (0.1ms) SELECT 1 AS one FROM "tags" WHERE "tags "."name" = 'a_tag' 限制 1

SQL (0.2ms) INSERT INTO "tags" ("name") VALUES (?) [["name", "a_tag"]]

ActsAsTaggableOn::Tag Load (0.1ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 13 AND "taggings"."taggable_type" = 'Photo' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)

ActsAsTaggableOn::Tagging Exists (0.2ms) SELECT 1 AS one FROM "taggings" WHERE ("taggings"."tag_id" = 16 AND "taggings"."taggable_type" = 'Photo' AND "taggings"."taggable_id" = 13 AND "taggings"."context" = 'tags' AND "taggings"."tagger_id" IS NULL AND "taggings"."tagger_type" IS NULL)限制 1

SQL (0.7ms) INSERT INTO "taggings" ("context", "created_at", "tag_id", "taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ? , ?, ?) [["context", "tags"], ["created_at", Fri, 28 Sep 2012 05:39:59 UTC +00:00], ["tag_id", 16], ["taggable_id" , 13], ["taggable_type", "Photo"], ["tagger_id", nil], ["tagger_type", nil]]

(4.1ms) 提交事务

(0.1ms) 开始交易

ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" WHERE (lower(name) = 'a_tag')

ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 13 AND "taggings"."taggable_type" = 'Photo' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)

CACHE (0.0ms) SELECT "tags".* FROM "tags" WHERE (lower(name) = 'a_tag')

ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 13 AND "taggings"."taggable_type" = 'Photo' AND (taggings.context = 'tags' AND taggings.tagger_id = 1 AND taggings.tagger_type = 'User')

ActsAsTaggableOn::Tagging Exists (0.4ms) SELECT 1 AS one FROM "taggings" WHERE ("taggings"."tag_id" = 16 AND "taggings"."taggable_type" = 'Photo' AND "taggings"."taggable_id" = 13 AND "taggings"."context" = 'tags' AND "taggings"."tagger_id" = 1 AND "taggings"."tagger_type" = 'User') 限制 1

SQL (0.5ms) INSERT INTO "taggings" ("context", "created_at", "tag_id", "taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ? , ?, ?) [["context", "tags"], ["created_at", Fri, 28 Sep 2012 05:39:59 UTC +00:00], ["tag_id", 16], ["taggable_id" , 13], ["taggable_type", "Photo"], ["tagger_id", 1], ["tagger_type", "User"]]

(2.4ms) 提交事务

4

2 回答 2

2

好的,这真的很奇怪,但我已经想出了如何避免这个问题。

我做的第一件事是创建一个尖峰解决方案来测试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 中关于批量分配的更改,并决定不损害安全性。

所以我添加到我的照片模型类

 attr_accessible :tag_list

这解决了错误但是当我测试它时我发现现在出现的重复行!所以现在这个错误是可重现的!

我通过更改表单来解决它,这样我就不会将表单绑定到 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)

这解决了问题!

我现在将尝试调查究竟为什么会发生这种情况!:)

于 2012-09-28T23:25:38.063 回答
2

我知道这个问题已经有五年的历史了,但这仍然发生在 Rails 5.1 中acts-as-taggable 4.0,我只是想向遇到这个问题的人展示它是如何解决的。

这是一个非常简单的修复,在控制器中的强大参数中,您只需添加tag_list: []而不是:tag_list像这样:

def photo_params
  params.require(:photo).permit(:title, tag_list: [])
end

Taggings这会阻止在数据库中创建重复和空白,您可以使用 aform_for而不是 aform_tag

<%= form_for @photo do |f| %>
  <%= f.text_field :title %>
  <%= f.text_field :tag_list %>
  <%= f.submit %>
<% end %>
于 2017-10-29T10:17:54.383 回答