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

奇妙なことに、最初の行の「tagger_id」と「tagger_type」が NULL に設定されているのに、「taggings」テーブルに重複行があり、重複行には正しい値が含まれています。

私のGemfileは次のようになります

gem 'rails', '3.2.8'
gem 'acts-as-taggable-on', '~> 2.3.1'

誰もこの動作を見たことがありますか? それは私の側の設定の問題ですか?

更新: コンソールを見ると、2 つのトランザクションが実行されていることがはっきりとわかります。最初のトランザクションには次のようなものがあります。

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 に設定されていることは明らかです。

これは完全なコンソール出力です。読みやすいように行を分けています。2 つの別個のトランザクションに気付くでしょう。最初のトランザクションには NULL 値の挿入があり、2 番目のトランザクションの最後には正しいトランザクションが表示されます。

127.0.0.1 の POST "/photo" を 2012-09-28 07:39:58 +0200 で開始 HTML パラメーターとして PhotoController#create で処理: {"utf8"=>"✓", "authenticity_token"=>"IOmnfDpU7V7vYw3h6RXXzXPsXf/ B0fcVihXhb+S8JHU=", "写真"=>{"url"=>"www.another.com/photo.jpg", "タイトル"=>"別", "tag_list"=>"a_tag", "説明" =>"", "private"=>"0"}, "commit"=>"Add Photo"} http://www.somedomain.com:3000/users/christiangiacomiにリダイレクト

完了 302 発見 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 JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" IS NULL AND "taggings"."taggable_type" = 'Photo' AND (taggings.context = 'tags ' AND taggings.tagger_id IS 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' LIMIT 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" = '写真' 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) LIMIT 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], ["tagger_type", "写真"], ["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" = '写真' 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" = '写真' AND (taggings.context = 'tags' AND taggings.tagger_id = 1 AND taggings.tagger_type = 'ユーザー')

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') LIMIT 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], ["tagger_type", "写真"], ["tagger_id", 1], ["tagger_type", "ユーザー"]]

(2.4ms) トランザクションをコミット

4

2 に答える 2

2

わかりました、これは本当に奇妙ですが、問題を回避する方法を見つけました。

最初に行ったのは、acts_as_taggable_on をテストするためのスパイク ソリューションを作成することでした。それは 2 つのモデル クラスで構成されており、それだけです...そして、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

これでエラーは解決しましたが、テストしたところ、現在表示されている行が重複していることがわかりました! これでバグは再現可能になりました!!

フォームを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 に答える