【问题标题】:Rails 4: Autocomplete nor working using rails4-autocomplete gemRails 4:使用 rails 4-autocomplete gem 无法自动完成
【发布时间】:2015-03-07 00:18:04
【问题描述】:

我有 3 个具有 has_many through 关系的模型:Food(例如:Chocolate)、Sub(巧克力食品替代品)、Joint(联合表)。

我正在使用 rails4-autocomplete gem 对保存在数据库中的现有替代品(来自我的子模型)进行简单的自动完成,这样当我创建新食物(食物模型)时,我可以关联这个“新食物”如果我愿意,可以使用现有的替代品。我按照gem doc 的步骤进行操作,但无法正常工作。

我的问题是使自动完成工作,以便在填写表格时(在视图/食物/_form 中)它显示已经存在的替代品(与我的子模型一起保存)

非常感谢您的帮助,请在下面找到所有相关代码:

application.js:(这里我需要自动完成轨道)

//= require jquery
//= require jquery_ujs
//= require cocoon
//= require turbolinks
//= require autocomplete-rails
//= require_tree .

我的路线:

  resources :foods do
    get :autocomplete_sub_name, :on => :collection
  end
  
  resources :subs

  resources :joints

  root "foods#index"

我的 3 个模型:

class Food < ActiveRecord::Base
    has_many :joints
    has_many :subs, :through => :joints
    accepts_nested_attributes_for :subs, reject_if: :all_blank, allow_destroy: true
end
class Sub < ActiveRecord::Base
    has_many :joints
    has_many :foods, :through => :joints
    accepts_nested_attributes_for :foods, reject_if: :all_blank, allow_destroy: true
end
class Joint < ActiveRecord::Base
    belongs_to :food
    belongs_to :sub
end

我的食物管理员:

class FoodsController < ApplicationController
  before_action :set_food, only: [:show, :edit, :update, :destroy]
  autocomplete :sub, :name, :full => true

  # GET /foods
  # GET /foods.json
  def index
    @foods = Food.all
  end

  # GET /foods/1
  # GET /foods/1.json
  def show
  end

  # GET /foods/new
  def new
    @food = Food.new
    @food.subs.build
  end

  # GET /foods/1/edit
  def edit
  end

  # POST /foods
  # POST /foods.json
  def create
    @food = Food.new(food_params)

    respond_to do |format|
      if @food.save
        format.html { redirect_to @food, notice: 'Food was successfully created.' }
        format.json { render :show, status: :created, location: @food }
      else
        format.html { render :new }
        format.json { render json: @food.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /foods/1
  # PATCH/PUT /foods/1.json
  def update
    respond_to do |format|
      if @food.update(food_params)
        format.html { redirect_to @food, notice: 'Food was successfully updated.' }
        format.json { render :show, status: :ok, location: @food }
      else
        format.html { render :edit }
        format.json { render json: @food.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /foods/1
  # DELETE /foods/1.json
  def destroy
    @food.destroy
    respond_to do |format|
      format.html { redirect_to foods_url, notice: 'Food was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_food
      @food = Food.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def food_params
      params.require(:food).permit(:name, :description, subs_attributes: [:id, :name, :description, :_destroy])
    end
end

我的数据库模式仅供参考:

create_table "foods", force: true do |t|
    t.string   "name"
    t.text     "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

  create_table "joints", force: true do |t|
    t.integer  "food_id"
    t.integer  "sub_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "subs", force: true do |t|
    t.string   "name"
    t.text     "description"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

最后是 mi _form 和 _sub_fields,这是部分呈现在 _form 中,我尝试使用自动完成功能:

<%= form_for(@food) do |f| %>
  <% if @food.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@food.errors.count, "error") %> prohibited this food from being saved:</h2>

      <ul>
      <% @food.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>

  <div>
    <%= f.fields_for :subs do |sub| %>
      <%= render 'sub_fields', :f => sub %>
      <%= link_to_add_association 'Add sub', f, :subs %>
    <% end %>
  </div>

  
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

_sub_fields 部分:

<div class="nested-fields">
    <div class="field">
        <%= f.label :name %>
        <%= f.text_field :name %>
        <%= f.autocomplete_field :sub_name, autocomplete_sub_name_foods_path %>

    </div>
    <div class="field">
        <%= f.label :description %>
        <%= f.text_area :description %>
    </div>
    <%= link_to_remove_association 'remove sub', f %>
</div>

非常感谢您的帮助! 安托万

【问题讨论】:

    标签: ruby-on-rails autocomplete has-many-through


    【解决方案1】:

    从您的所有代码中,我只能猜测您的问题的可能原因:

    您在嵌套模型表单中使用自动完成字段。 link_to_add_association-Link 将新元素动态添加到页面。注意新添加的元素附加了必要的 Javascript 事件处理程序。 gem 的 Javascript 包含以下几行:

    jQuery(document).ready(function(){
      jQuery('input[data-autocomplete]').railsAutocomplete()
    });
    

    所以事件处理程序只附加到页面完全加载后已经存在的元素。尝试将这些行更改为:

    jQuery(document).ready(function(){
      jQuery('body').on('focus', 'input[data-autocomplete]', function(){
        jQuery(this).railsAutocomplete()
      })
    })
    

    这样,您每次添加一组新的嵌套字段时都会附加事件处理程序。

    【讨论】:

      猜你喜欢
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多