ruby-on-rails - 在不清除标记的行为上作为可标记的 gem 的奇怪行为

标签 ruby-on-rails ruby ruby-on-rails-4 acts-as-taggable-on

我有一个名为 Recipe 的模型,它使用 acts-as-taggable-on gem 为食谱添加标签。奇怪的行为是当我通过 Controller 编辑和更新配方时,配方标签被添加而不是更新为正确的标签。有一个类似的 Github issue被举报,但没有任何人回复。我的 acts-as-taggable-on gem 版本是 3.2.6。

例如,我的食谱有三个标签:fruitfruitvegetablesfruit 标签不相关,所以我在我的 f.tag_list 输入字段中删除了这两个 fruit 标签,只包含 vegetables.

Processing by Users::RecipesController#update as JS
Parameters: {"utf8"=>"✓", "recipe"=>{"image_ids"=>"46746", "cover_image_id"=>"46746",
"name"=>"Cauliflower", "description"=>"this is the description", "preparation_time_hr"=>"0",
"preparation_time_min"=>"50", "servings"=>"4", 
"category_ids"=>"", "cuisine_ids"=>"", "tag_list"=>"vegetables", "ingredients"=>....}

用户/recipes_controller.rb

def update
  if @recipe.update_attributes(recipe_params)
    if params[:publish_recipe] && params[:publish_recipe] == "true"
      update_status!(:publish!)
    end
    redirect_to user_recipes_url
  else
    respond_to do |format|
      format.html{ render "edit" }
      format.js { render partial: "shared/flash_message", locals: { flash_type: "error", flash_message: "#{@recipe.errors.full_messages.to_sentence}" } }
    end
  end
end

recipe_params 包含 tag_list 作为允许的参数。

def recipe_params
  params.required(:recipe).permit(:name, :category_ids, :cuisine_ids, :tag_list, :preparation_time_hr,
  :cover_image_id, :preparation_time_min, :servings, :description, :image_ids, :commentable,
  ingredients_attributes: [:id, :name, :_destroy],
  instructions_attributes: [:id, :text, :_destroy, image_attributes: [:id, :picture, :_destroy]]
) rescue {}
end

但最终旧的标签没有被删除,新的标签被添加到列表中:fruit, fruit, vegetables , 蔬菜

另一件奇怪的事情是,当我尝试查看食谱的 tag_list 时,它是一个空数组。尝试在 Rails 控制台中编辑 tag_list,它添加了另一个标记,但是当我执行 r.reload 时,tag_list 它仍然是一个空数组。现在食谱和标签之间的关系是这样的:

r = Recipe.find(20980)
[56] pry(main)> r.tag_list
 ActsAsTaggableOn::Tag Load (14.9ms)  SELECT `tags`.* FROM `tags` INNER JOIN `taggings` ON `tags`.`id` = `taggings`.`tag_id` WHERE `taggings`.`taggable_id` = 20980 AND `taggings`.`taggable_type` = 'Recipe' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)
=> []
[57] pry(main)> r.tags
=> [#<ActsAsTaggableOn::Tag id: 2, name: "fruit", taggings_count: 1138, tagger_id: nil, tagger_type: nil, created_at: "2015-07-25 15:47:20", updated_at: "2015-07-25 15:47:53">,
 #<ActsAsTaggableOn::Tag id: 2, name: "fruit", taggings_count: 1138, tagger_id: nil, tagger_type: nil, created_at: "2015-07-25 15:47:20", updated_at: "2015-07-25 15:47:53">,
 #<ActsAsTaggableOn::Tag id: 531, name: "vegetables", taggings_count: 21, tagger_id: nil, tagger_type: nil, created_at: "2015-07-25 15:56:15", updated_at: "2015-07-25 15:56:16">,
 #<ActsAsTaggableOn::Tag id: 531, name: "vegetables", taggings_count: 21, tagger_id: nil, tagger_type: nil, created_at: "2015-07-25 15:56:15", updated_at: "2015-07-25 15:56:16">,
 #<ActsAsTaggableOn::Tag id: 531, name: "vegetables", taggings_count: 21, tagger_id: nil, tagger_type: nil, created_at: "2015-07-25 15:56:15", updated_at: "2015-07-25 15:56:16">]
[58] pry(main)> r.taggings
  ActsAsTaggableOn::Tagging Load (35.8ms)  SELECT `taggings`.* FROM `taggings`  WHERE `taggings`.`taggable_id` = 20980 AND `taggings`.`taggable_type` = 'Recipe'
=> [#<ActsAsTaggableOn::Tagging id: 20408, tag_id: 2, taggable_id: 20980, taggable_type: "Recipe", tagger_id: 200422, tagger_type: "User", context: "tags", created_at: "2015-08-21 03:56:13">,
 #<ActsAsTaggableOn::Tagging id: 20409, tag_id: 2, taggable_id: 20980, taggable_type: "Recipe", tagger_id: 200422, tagger_type: "User", context: "tags", created_at: "2015-08-21 03:56:14">,
 #<ActsAsTaggableOn::Tagging id: 20410, tag_id: 531, taggable_id: 20980, taggable_type: "Recipe", tagger_id: 200422, tagger_type: "User", context: "tags", created_at: "2015-08-21 04:01:36">,
 #<ActsAsTaggableOn::Tagging id: 20411, tag_id: 531, taggable_id: 20980, taggable_type: "Recipe", tagger_id: 200422, tagger_type: "User", context: "tags", created_at: "2015-08-21 04:47:38">,
 #<ActsAsTaggableOn::Tagging id: 20412, tag_id: 531, taggable_id: 20980, taggable_type: "Recipe", tagger_id: 200422, tagger_type: "User", context: "tags", created_at: "2015-08-21 04:53:38">]

tag_list 数据库查询也很奇怪,为什么查询包含这个 taggings.tagger_id IS NULL

我对这个 gem 还是个新手,知道如何使用 gem 方法正确更新标签吗?我希望我可以避免使用我自己的代码更新标签以避免进一步的问题。请注意,我的 Recipe 模型由 paper_trail 控制版本。 gem,我希望它与这个问题无关。

最佳答案

由于网上没有解决方案,我只在Recipe上使用这个taggable,所以现在我手动调用一个方法来在模型保存后重新更新标签。

def update_tags(tag_list)
  self.taggings.destroy_all
  list = tag_list.split(",")
  list.each do |t|
    tag = Tag.find_or_create_by(name: t)
    self.taggings.create(tag_id: tag.id, context: "tags")
  end
  return self.taggings
end

我仍然认为这个问题有更好的解决方案,我愿意接受替代方案作为最佳答案。

关于ruby-on-rails - 在不清除标记的行为上作为可标记的 gem 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32134322/

相关文章:

ruby-on-rails - 在我的 Rails 应用程序中添加谷歌地图 - 需要帮助开始而不使用 Gem - 想编写自定义代码

ruby-on-rails - Rails 4 Assets 管道未找到预编译 CSS 文件

ruby-on-rails - 如何交错多个 ActiveRecord 关联查询?

ruby-on-rails - 跳过rails counter_cache更新

mysql - 将 Rails 路由中的参数限制为 INT(11) 范围

ruby-on-rails - Rails 4 原始 html_safe 不起作用

ruby-on-rails - created_at字段有时变为nil

ruby - 在 Ruby 中用空格拆分

ruby-on-rails - update_attributes和直接设置为nil的区别

ruby-on-rails - Rails4 : Link to A Controller