[英]What is wrong with my association?
我希望建立一種關系,用戶可以在其中創建帖子並標記該帖子。 該帖子和這些標簽屬於該用戶。
最近三天,我一直在嘗試調試此問題。 我不知道為什么保存我的帖子時,在tag模型中沒有填充user_id。 我將user_id添加到Tag模型中。
對於過多的代碼,我事先表示歉意。
用戶-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
如果我丟失了某些內容,我深表歉意,但是看起來您在創建標簽時沒有將用戶ID傳遞給標簽。 使用rails 3,您可以為多個屬性執行find_or_create_by,如下所示:
tag = Tag.find_or_create_by_name_and_user_id(tag_name, user_id)
此外,如果只想構建Tag對象,而不是立即將其保存到數據庫,則可以使用“ find_or_initialize_by ...”方法,如下所示:
tag = Tag.find_or_initialize_by_name_and_user(tag_name, user)
只要確保您的Tag模型還沒有attr_accessible :user_id
,就可以了。
更新:對不起,我只是重新閱讀了您的問題,您說您確實將user_id傳遞給了標記模型。 但是,在您提供的代碼中我看不到這一點。 在哪里發生?
更新#2基於注釋線程,您的參數映射不包含user_id。 當然,這是因為參數映射是根據表單輸入構建的,該表單輸入顯然不包含用戶輸入。
我假設在創建帖子時,該帖子應與當前登錄的用戶相關聯。 我還將假設您在某處有一個對當前登錄用戶的引用,我將其稱為@current_user。
由於看起來您想在一個原子操作中創建post和相關標簽,因此您可以將當前用戶添加到參數映射的副本中,如下所示:
post_params = params.clone.store(:user=>@current_user)
@post = Post.new(post_params)
也許有更好的方法可以做到這一點,但這應該行得通。 請注意,您可能不需要克隆參數映射。 我不知道這種情況下的最佳做法是什么。
無論如何,希望能有所幫助。
更新3由於Ruby哈希是按照插入鍵的順序進行迭代的,因此在將user_id插入Post模型之前,已將svn的tag_ids設置為。 為了解決該問題,svn顛倒了我先前建議的順序,並確保在其他任何值之前插入了:user鍵。 這是一種可能的解決方案(從svn的要點(https://gist.github.com/4027807修改)):
post_params = {:user => current_user}.merge!(params[:post].clone)
@post = Post.new(post_params)
在控制器中的行之前,
@post = Post.new(params[:post])
在行下方添加
@post = Post.new(:user_id => <assign your required user_id>)
這將使新的post對象在其instace方法內使用user_id。
然后您將可以成功使用下面的行
tag = Tag.find_or_create_by_name_and_user_id(tag_name, user_id)
希望能幫助到你 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.