【问题标题】:Trouble saving tags in Ruby on Rails 4 with acts_as_taggable使用acts_as_taggable在Ruby on Rails 4中保存标签时遇到问题
【发布时间】:2013-10-24 04:18:22
【问题描述】:

我正在尝试在我的 Rails 4 应用程序中实现 act_as_taggable(基于 microposts 模型),但程序没有保存标签,因此无法查看。标签和标签的表格已被收集并存在于数据库中,但我实现的代码似乎都没有在提交表单时保存标签或创建标签。我完全按照tutorial 中的步骤进行操作,但似乎没有什么效果。

我不确定这是否是以 rails 4 为中心的问题和/或与 rails 中缺少“attr_accessible”代码有关。由于代码示例没有指定向 microposts 表添加任何内容,因此我只能假设连接是在其他地方建立的,但是我不知道应该在哪里以及如何修复它(也许在 microposts_helper.rb 中?)。

提前致谢。非常感谢任何帮助。

相关代码片段

宝石文件

...

gem 'acts-as-taggable-on', '~> 2.4.1'

...

microposts.rb

   class Micropost < ActiveRecord::Base     
   belongs_to :user  
   acts_as_taggable   
   acts_as_taggable_on :tags
   ... 
   end

microposts_controller.rb

  before_action :signed_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy

  def index
    if params[:tag]
      @microposts = Micropost.tagged_with(params[:tag])
    else
      @microposts = Micropost.all
    end
  end

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to current_user
    else
      @feed_items = []
      render 'users/show'
    end
  end

  def destroy
    @micropost.destroy
    redirect_to user_url
  end

  def tagged
    if params[:tag].present? 
      @microposts = Micropost.tagged_with(params[:tag])
    else 
      @microposts = Micropost.postall
    end  
  end

  private

    def micropost_params
      params.require(:micropost).permit(:content)
    end

    def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])
      redirect_to user_url if @micropost.nil?
    end
end

microposts_helper.rb

module MicropostsHelper
    include ActsAsTaggableOn::TagsHelper
end

_microposts_form.html.rb

<%= form_for(@micropost) do |f| %>
  ...
  <div class="field">
    ...
    <%= f.label :tags %>
    <%= f.text_field :tag_list %>
  </div>
  <%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>

_micropost.erb.html

<li>
  <span class="content"><%= micropost.content %></span>
  <span class="tags">
    <%= micropost.tag_list %>
  </span>
...
</li>

schema.rb

...
create_table "microposts", force: true do |t|
    t.string   "content"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "microposts", ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at"
...
  create_table "taggings", force: true do |t|
    t.integer  "tag_id"
    t.integer  "taggable_id"
    t.string   "taggable_type"
    t.integer  "tagger_id"
    t.string   "tagger_type"
    t.string   "context",       limit: 128
    t.datetime "created_at"
  end

  add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id"
  add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"

  create_table "tags", force: true do |t|
    t.string "name"
  end
...

routes.rb

Dev::Application.routes.draw do
    ...
    resources :microposts, only: [:create, :destroy]
    ...
    match 'tagged', to: 'microposts#tagged', :as => 'tagged', via: 'get' 
end

【问题讨论】:

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


    【解决方案1】:

    如果我正确理解了这个问题,那么您需要做的就是基本上告诉 params(strong_parameters) 的推荐保护模型关于作为可标记的 gem。你已经成功了:

    private
    
        def micropost_params
          params.require(:micropost).permit(:content)
        end
    
        [...]
    end
    

    只需添加:

    private
    
        def micropost_params
         params.require(:micropost).permit(:content, :tag_list => [])
        end
    
        [...]
    end
    

    另外,您可能想在您的 routes.rb 文件中添加一件事。替换行:

    resources :microposts, only: [:create, :destroy]
    

    与:

    resources :microposts, only: [:create, :destroy, :tag]
    

    如果这些建议有效,请告诉我。祝你好运!

    【讨论】:

    • 感谢您的回答。是的,我确实做到了这一点,但忘记更新原始问题。你是 100& 正确的。
    【解决方案2】:

    我认为,表单中标签的输入变量应该是tags_list。即

    <%= form_for(@micropost) do |f| %>
      ...
      <div class="field">
        ...
        <%= f.label :tags %>
        <%= f.text_field :tags_list %>
      </div>
      <%= f.submit "Post", class: "btn btn-large btn-primary" %>
    <% end %>
    

    同时更新_micropost.erb.html 以使用tags_list。

    或者你可以只更新你的模型以使用标签属性,即'acts_as_taggable_on :tag'

    【讨论】:

    • 使用 tags_list 会导致错误,因为“未定义的方法 tags_list' for #&lt;Micropost:0x3efb6e0&gt;". By adding a tag attribute to you mean with attr_accessible? Adding that to rails 4 gives me "attr_accessible` 被从 Rails 中提取到 gem 中。请为 params(strong_parameters) 使用新的推荐保护模型或将 protected_attributes 添加到你的 Gemfile 使用旧的。”我想有办法解决这个问题,但是感觉 act_as_taggable 应该与 rails 4 兼容,如果我能发现我做错了就好了。不过感谢您的帮助。
    • @James:这就是我实现并为我工作的方式gist.github.com/neutrino/7132567。因为,我正在使用旧应用程序中的模型和视图,所以我现在在我的 Gemfile 中包含了 protected_attributes gem。
    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 2012-09-15
    相关资源
    最近更新 更多