質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.94%

【Rails5】オートコンプリート付きのタグ入力の実装~jQuery plugin~

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 425

score 4

ユーザーの投稿する記事に複数のキーワードを紐づけ、キーワードの入力フォームに自動予測機能(オートコンプリート)を加えて入力時にバッジ風な見せ方にしたいと考えています。
【Rails5】オートコンプリート付きのタグ入力 〜バッジ風〜
上記の記事を参考に新規投稿は問題なく実装する事ができたのですが、
編集ページにおいて投稿された記事の編集時にキーワードも編集し追加・削除したいと思うのですが思うような挙動が得られずに困っています。

・複数タグが記事に登録されていると編集ページでキーワードフォームがタグの数だけ生成されてしまう。
キーワードフォーム一つでタグが横並びし追加・削除を行いたいと考えています。
・編集ページで登録済のキーワードをフォームから削除しても記事に登録されたままになってしまう。
記事自体を削除しなければ削除できない状況です。

お分かりになる方いらっしゃればご教授お願い致します。

posts.js

$(document).on('turbolinks:load',function(){

  $('#formTagInput').tagsInput({
    'autocomplete_url': "/keywords/autocomplete.json",
    'autocomplete': {
      focus: function(event, ui){
        $('#formTagInput_keyword').val(ui.item.name);
        return false;
      },
      select: function(event, ui) {
        $('#formTagInput').addTag(ui.item.name);
        return false;
      }
    },
    'height:': 'calc(2.25rem + 2px)',
    'width': '100%',
    'defaultText': ''
  })

  if($("#formTagInput_keyword").length){
    $('#formTagInput_keyword').data('ui-autocomplete')._renderItem = function(ul, item) {
      return $('<li class="w-100">').data('item.autocomplete', item).append('<a class="w-100 d-flex">' + item.name + '</a>')
        .appendTo(ul);
    }  
  }

});

postモデル

class Post < ApplicationRecord
  has_many :posts_keywords, dependent: :destroy
  has_many :keywords, through: :posts_keywords
  accepts_nested_attributes_for :keywords, :reject_if => proc { |att| att[:name].blank?}
  before_save :find_or_create_keyword

  private

  def find_or_create_keyword
    keyword_array = [] 
    self.keywords.map{ |keyword| 
        keyword.name.strip.split(",").each do |name|
          keyword_array << name
        end
      }
      self.keywords.destroy_all
      keyword_array.each do |keyword|
        self.keywords << Keyword.find_or_create_by(name: keyword)
      end            
  end
end


keywordモデル

class Keyword < ApplicationRecord
  validates :name,presence:true,length:{maximum:30}

  has_many :posts_keywords, dependent: :destroy
  has_many :posts, through: :posts_keywords
end


中間テーブル

class PostsKeyword < ApplicationRecord
  belongs_to :post
  belongs_to :keyword
end


postsコントローラー

 def new
    @post = current_user.posts.build
    @post.keywords.build
  end

  def create
    @post = current_user.posts.build(post_params,)
    if @post.save
      flash[:success] = 'プランを投稿しました。'
      redirect_to user_path(@post.user_id)
    else
      flash[:danger] = 'プランの投稿に失敗しました。'
      render :new 
    end
  end

  def edit
    @post = Post.find(params[:id])
  end

  def update
    @post = Post.find(params[:id])

    if @post.update(post_params)
      flash[:success] = '正常に更新されました'
      redirect_to post_path
    else
      flash.now[:danger] = '更新されませんでした'
      render :edit
    end
  end

  def keywordAutocomplete
    @keywords = Keyword.includes(:posts).all.where('name LIKE ?', "%#{params[:term]}%")
    render json: @keywords.map{ |keyword| {name:keyword.name, count: keyword.posts.size}}.to_json
  end

  private

  def post_params
    params.require(:post).permit(:post_title, :content, :user_id,
    {schedules_attributes: [省略]},
    {keywords_attributes: [:name, :_destroy, :id]})
  end


view

<%= form_with(model: @post, local: true) do |f| %>
<div class="form-group">
        <%= f.fields_for :keywords do |tf| %>
          <%= tf.label :name, "キーワード"  %>
          <%= tf.text_field :name, id:"formKeywordInput", class:"form-control" %>
        <% end %>
      </div>
<% end %>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.94%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る