2017-07-21 12 views
0

多くのユーザーがいるチームのモデルがあります。ユーザーはhas_many :throughのようなチームのモデルに関連付けられています。 ユーザを検索したり、ユーザを選択したときにネストされたフィールドを追加したりするときに、フィールドを自動補完する必要があります。Rails 5とAJAX - オートコンプリートとネストされたフォームの保存はできません。

アプリ/コントローラ/ teams_controller.rb

class TeamsController < ApplicationController 

    # GET /teams/new 
    def new 
    @team = Team.new #(parent_id: params[:parent_id]) 
    end 

    # GET /teams/1/edit 
    def edit 
    end 

    # POST /teams 
    def create 
    @team = Team.new(team_params) 

    respond_to do |format| 
     if @team.save 
     format.html { redirect_to @team, success: t('.flash.success.message') } 
     else 
     format.html { render :new, danger: t('.flash.danger.message') } 
     end 
    end 
    end 

    # GET /teams/1/search_team_user 
    def search_team_user 
    @users = User.order(:first_name).where("first_name like ?", "%#{params[:term]}%") 
    render json: @users.map { |u| { value: u.id, label: u.name } } 
    end 

    # GET /teams/1/new_team_user 
    def new_team_user 
    @team = Team.find(params[:id]) 
    @new_team_user = @team.team_users.build(user_id: params[:user_id]) 
    end 

    private 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def team_params 
     params.require(:team).permit(
     :name, 
     :parent_id, 
     team_users_attributes: [:_destroy, :id, :user_id] 
    ) 
    end 
end 

アプリ/設定/ routes.rbを

resources :teams do 
    get :search_team_user, on: :member 
    get :new_team_user, on: :member 
end 

アプリ/ビュー/チーム/ _form.html.erb

<%= form_for(@team) do |f| %> 
    <div class='row'> 
    <div class='<%= column_class %>'> 
     <div class='form-group row'> 
     <div class='<%= dynamic_small_column_class %>'> 
      Team membership 
     </div> 
     <div class='<%= dynamic_large_column_class %>'> 
      <div id='team-user-select' class='new-nested-group mb-3'> 
      <%= text_field_tag 'search_team_users', nil, class: 'form-control autocomplete autocomplete-search new-nested-object', data: { autocomplete_object_id: true, autocomplete_source: search_team_user_team_path(@team), new_nested_object_path: new_team_user_team_path(@team) } %> 
      <%= hidden_field_tag 'user_id', nil, class: 'autocomplete autocomplete-value new-nested-object' %> 
      </div> 
      <div id='team-users' class='nested-objects'> 
      <%= render 'team_user_fields', f: f, team_users: @team_users, child_index: nil %> 
      </div> 
     </div> 
     </div><!-- /.form-group.row --> 
    </div><!-- /.col --> 
    </div><!-- /.row --> 
    <hr class='my-5'> 
    <div class='row'> 
    <div class='<%= column_class %>'> 
     <div class='pull-right'> 
     <%= cancel_link %> 
     <%= save_link %> 
     </div> 
    </div><!-- /.col --> 
    </div><!-- /.row --> 
<% end %> 

アプリ/ビュー/チーム/ new_team_user.js.erb

$('#team-users').append("<%= j(fields_for(@team) { |f| render('team_user_fields', f: f, team_users: @new_team_user, child_index: Time.now.to_i) }) %>"); 

APP /資産/ JavaScriptの/ nested_form.coffee

# # Autocomplete plagin 
# 
$.fn.customAutocomplete = -> 
    @each (i, el) -> 
    el = $(el) 
    el.autocomplete 
     minLength: 1 
     source: el.data('autocomplete-source') 
     focus: (event, ui) -> 
     el.val ui.item.label 
     false 
     select: (event, ui) -> 
     el.val '' 
     el.next('.autocomplete.autocomplete-value').val ui.item.value 

     url = el.data("new-nested-object-path") 
     data = $('.new-nested-group :input, .new-nested-object').serialize() 

     $.ajax 
      url: url 
      data: data 
      dataType: 'script' 
     false 

# # Delete nested item 
removeNestedObject = (element, objName) -> 
    $("[name='"+objName+"[_destroy]']").val true 
    $(element).closest('.removable-nested-object').remove() 

$(document).on 'click', 'a.remove-nested-object', -> 
    objName = $(this).data('object-name') 
    removeNestedObject(this, objName) 

# # On load 
# 
$(document).on 'turbolinks:load', -> 

    $('a.add-nested-object').click (e) -> 
    e.preventDefault() 

    url = @href 
    data = $('.new-nested-group :input, .new-nested-object').serialize() 

    $.ajax 
     url: url 
     data: data 
     dataType: 'script' 

    $('.autocomplete.autocomplete-search').customAutocomplete() 

このコードは、移行時にこのエラーを生成チームの新しいページ:

/Users/nikolaylipovtsev/Documents/Projects/inbox_t依頼/アプリ/ビュー/チーム/ _form.html.erb回線#23が上昇しない :

Noルートマッチ{:アクション=> "search_team_user":コントローラ=> "チーム"、 :IDを=># 、:locale =>:ru}欠落が必要です keys:[:id]

変更する必要はありますか?

答えて

0

次のルートは、有効なidとチームは@teamがそのようにそのid属性がnilである@team = Team.newで作成され、新しいチームのページで

get :search_team_user, on: :member 

を必要とされることを意味します。これはまさにエラーの内容です

{:action => "search_team_user"、:controller => "teams"、:id =>#、:locale =>:ru}一致するルートはありません: :id]

TeamsController#search_team_userでは、私はこのアクションがチームを正しく実行する必要はないことがわかります。この問題を解決するには、ルートを

に変更することができます
resources :teams do 
    get :search_team_user, on: :collection 
    get :new_team_user, on: :member 
end 
+0

はい、チーム[:id]にはTeamsController#new_team_userが必要です。これは、正しい保存関連付けの必要性です。 –

+0

@NikolayLipovtsevルートを見ると、 'new_team_user'はまだメンバ上にあります。 – Hoa

+0

そして、このパス 'new_team_user'は新しいビューにあります。エラー '%%text_field_tag' search_team_users '、nil、class:' form-control autocomplete-search new-nested-object '、データ:{autocomplete_object_id :true、autocomplete_source:search_team_user_team_path(@team)、new_nested_object_path:new_team_user_team_path(@team)}%> ' –

関連する問題