Trouble saving tags in Ruby on Rails 4 with acts_a

2019-04-02 05:10发布

I'm trying to implement act_as_taggable into my Rails 4 app (upon the microposts model), but the program isn't saving the tags, which therefore aren't viewable. The tables for tags and taggings have been raked and exist in the database, but none of the code I'm implemented seems to save a tag or create a tag when the form is submitted. I followed the steps in this tutorial near exactly, but something doesn't seem to work.

I'm not sure if it's a rails 4 centric problem and/or is connected to the lack of 'attr_accessible' code used in rails. Since the code example doesn't specify adding anything to the microposts table, I can only assume the connection is made elsewhere, but where and how I should fix that I don't know (in microposts_helper.rb perhaps?).

Thanks in advance. Any help is greatly appreciated.

Relevant Code Snippets

Gemfile

...

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

2条回答
啃猪蹄的小仙女
2楼-- · 2019-04-02 05:13

I think, input variable for the tags in the form should tags_list. i.e

<%= 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 %>

And also update the _micropost.erb.html to use tags_list.

Or you can just update your with model to use a tag attribute instead i.e 'acts_as_taggable_on :tag'

查看更多
我命由我不由天
3楼-- · 2019-04-02 05:29

If I understand the question correctly, all you should need to do is, essentially, tell the recommended protection model for params(strong_parameters) about the acts-as-taggable gem. Your already Halfway there with this:

private

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

    [...]
end

Just add:

private

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

    [...]
end

Also, you may want to add one thing to your routes.rb file.. Replace the line:

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

with:

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

Let me know if these suggestions do the trick. Good luck!

查看更多
登录 后发表回答