0

我希望建立一种关系,用户可以在其中创建帖子并标记该帖子。该帖子和那些标签属于该用户。

在过去的三天里,我一直在尝试调试它。我不知道为什么当我保存我的帖子时,user_id 没有填充到 Tag 模型中。我将 user_id 添加到 Tag 模型中。

我提前为过多的代码道歉。

用户 - has_many 帖子;has_many 标签

发布 - 属于用户;has_many 标签;has_many 标签通过标签

Tag - 有很多标签;has_many 通过标签发布帖子;属于用户

标记 - belongs_to 帖子;属于_to 标签

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)

只要确保您的 Tag 模型有attr_accessible :user_id,如果它还没有。

更新:对不起,我刚刚重新阅读了您的问题,并且您说您确实将 user_id 传递给了标签模型。但是我在您提供的代码中看不到这一点;这发生在哪里?

更新 #2 根据评论线程,您的参数映射不包含 user_id;当然,这是因为参数映射是根据表单输入构建的,而表单输入显然不包含用户输入。

我假设创建帖子时,它应该与当前登录的用户相关联。我还将假设您在某个地方有对当前登录用户的引用,我将其称为@current_user。

由于看起来您想在一个原子操作中创建帖子和相关标签,您可以做一件事将当前用户添加到参数映射的副本中,如下所示:

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

可能有更好的方法可以做到这一点,但这应该可行。请注意,您可能不需要复制参数映射;我管理员我不确定在这种情况下什么是最佳实践。

无论如何,希望这会有所帮助。

更新 3 由于 Ruby 散列是按照插入键的顺序迭代的,所以 svn 的 tag_ids 是在他的 user_id 进入 Post 模型之前设置的。为了解决这个问题,svn 颠倒了我之前建议的顺序,并确保 :user 键被插入在任何其他值之前。这是一种可能的解决方案(根据 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>)

这将使新的 post 对象在其实例方法中使用 user_id。
然后你就可以使用了,下线成功

tag = Tag.find_or_create_by_name_and_user_id(tag_name, user_id)

希望能帮助到你 :)

于 2012-11-06T19:22:21.397 回答