0

ユーザーが投稿を作成し、その投稿にタグを付けることができる関係をセットアップしようとしています。その投稿とそれらのタグはそのユーザーのものです。

過去 3 日間、これをデバッグしようとしています。投稿を保存すると、user_id が Tag モデルに入力されない理由がわかりません。Tag モデルに user_id を追加しました。

過度のコードについては、あらかじめお詫び申し上げます。

ユーザー - has_many の投稿; has_many タグ

投稿 - ユーザーに属する; has_many のタグ付け; タグ付けによる has_many タグ

タグ - 多くのタグ付けがあります。タグ付けによる has_many の投稿。所属するユーザー

タグ付け - 投稿に属します。所属タグ

ActiveRecord::Schema.define(:version => 20121031012555) do

  create_table "posts", :force => true do |t|
    t.integer  "user_id"
    t.string   "summary"
    t.datetime "created_at",  :null => false
    t.datetime "updated_at",  :null => false
  end

  create_table "taggings", :force => true do |t|
    t.integer  "post_id"
    t.integer  "tag_id"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  add_index "taggings", ["post_id"], :name => "index_taggings_on_post_id"
  add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"

  create_table "tags", :force => true do |t|
    t.string   "name"
    t.integer  "user_id"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "users", :force => true do |t|
    t.string   "username"
    t.string   "email"
    t.string   "crypted_password"
    t.string   "password_salt"
    t.string   "persistence_token"
    t.datetime "created_at",        :null => false
    t.datetime "updated_at",        :null => false
    t.string   "role"
  end

end

投稿モデルで:

def tag_ids=(tags_string)
    self.taggings.destroy_all

    tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
    tag_names.each do |tag_name|
      tag = Tag.find_or_create_by_name(tag_name)
      tagging = self.taggings.new
      tagging.tag_id = tag.id
    end
end
4

2 に答える 2

1

何か不足していたら申し訳ありませんが、作成時にユーザー ID をタグに渡していないようです。Rails 3 では、次のように、複数の属性に対して find_or_create_by を実行できます。

tag = Tag.find_or_create_by_name_and_user_id(tag_name, user_id)

さらに、Tag オブジェクトを作成するだけで、すぐに DB に保存したくない場合は、次のように「find_or_initialize_by...」メソッドを使用できます。

tag = Tag.find_or_initialize_by_name_and_user(tag_name, user)

タグモデルがattr_accessible :user_idまだない場合は、それを確認してください。

更新:申し訳ありませんが、あなたの質問を読み直したところ、user_id をタグ モデルに渡すと述べました。ただし、提供されたコードではそれがわかりません。それはどこで起こりますか?

更新 #2 コメント スレッドに基づいて、パラメーター マップに user_id が含まれていません。これはもちろん、パラメーター マップがフォーム入力から構築されているためです。これには明らかにユーザーの入力が含まれていません。

投稿が作成されると、現在ログインしているユーザーに関連付けられる必要があると仮定しています。また、現在ログインしているユーザー (@current_user とします) への参照がどこかにあると仮定します。

投稿と関連するタグを 1 つのアトミック操作で作成したいように見えるので、次のように現在のユーザーをパラメーター マップのコピーに追加することができます。

post_params = params.clone.store(:user=>@current_user)
@post = Post.new(post_params)

これを行うためのより良い方法があるかもしれませんが、これはうまくいくはずです。おそらく、パラメーター マップのクローンを作成する必要はないことに注意してください。この場合のベストプラクティスが何であるかわかりません。

とにかく、それが役立つことを願っています。

更新 3 キーが挿入された順序で Ruby ハッシュが繰り返されるため、svn の tag_ids は Post モデルに user_id が設定される前に設定されていました。この問題を解決するために、svn は以前の提案の順序を逆にし、:user キーが他の値の前に挿入されるようにしました。これは1つの可能な解決策です(svnの要点(https://gist.github.com/4027807)から変更):

post_params = {:user => current_user}.merge!(params[:post].clone)
@post = Post.new(post_params)
于 2012-11-06T18:00:02.340 に答える
0

コントローラーの行の前に、

@post = Post.new(params[:post])

下の行に追加

@post = Post.new(:user_id => <assign your required user_id>)

これにより、新しい投稿オブジェクトがそのインスタンス メソッド内で user_id を使用するようになります。
次に、以下の行を正常に使用できるようになります

tag = Tag.find_or_create_by_name_and_user_id(tag_name, user_id)

それが役に立てば幸い :)

于 2012-11-06T19:22:21.397 に答える