代码之家  ›  专栏  ›  技术社区  ›  Lee McAlilly

如何使用selectize.js查找或创建属于关联的Rails?

  •  5
  • Lee McAlilly  · 技术社区  · 6 年前

    我很难弄清楚如何在Rails中组合 selectize.js 我想照张像这样的照片:

    我尝试过使用 接受嵌套的属性,但这似乎不适用于a 所属的属性。 relationship.

    我尝试过这样的自动完成关联 railscast插曲

    我真正想做的是使用selectize样式集合select创建“speaker”关联(如果它已经存在于数据库中),但如果它还不存在,则添加一个新的关联。selectize使我能够添加一个新的记录,但我在通过窗体传递该记录以在关联模型中创建新记录时遇到问题。

    这是我的模型:

    类引号<applicationrecord
    属于:演讲者,班级名称:“艺术家”
    属于:主题,类名:“艺术家”
    结束
    

    quote.rb

    类艺术家<applicationrecord
    有许多:口语语录,类名:“Quote”,外文键::演讲者ID
    有多个:topic_quotes,class_name:“quote”,foreign_key::topic_id
    结束
    

    artist.rb

    我的表格:

    “谁说的?”% gt; <%=f.collection_select:speaker_id,artist.order(:name),:id,:name,prompt:'select an artist',class:'form control select artist'%>

    u form.html.erb

    控制器:

    quotes ou controller.rb

    艺术家控制器.rb

    如何通过Quote.New Form通过选择性样式集合Select创建新的艺术家(作为“演讲者”)?selectize行为是我正在寻找的用户体验,我只是不知道如何通过报价表创建新的艺术家。

    enter image description here

    我尝试使用accepts_nested_attributes但这似乎不适用于belongs_to关系。

    我尝试过这样的自动完成关联railscast episode.

    我真正想做的是使用selectize样式集合select创建“speaker”关联(如果它已经存在于数据库中),但如果它还不存在,则添加一个新的关联。selectize使我能够添加一个新的记录,但我在通过窗体传递该记录以在关联模型中创建新记录时遇到问题。

    以下是我的模型:

    class Quote < ApplicationRecord
      belongs_to :speaker,  class_name: "Artist"
      belongs_to :topic,    class_name: "Artist"
    end
    

    Quote.rb

    class Artist < ApplicationRecord
      has_many :spoken_quotes, class_name: "Quote", foreign_key: :speaker_id
      has_many :topic_quotes,  class_name: "Quote", foreign_key: :topic_id
    end
    

    Artist.rb

    我的表格:

    <%= f.label :speaker, 'Who said it?' %>
    <%= f.collection_select :speaker_id, Artist.order(:name), :id, :name, {prompt: 'Select an artist'}, {class: 'form-control select-artist'} %>
    

    _form.html.erb

    控制器:

    quotes_controller.rb

    artists_controller.rb

    如何通过Quote.New Form通过选择性样式集合Select创建新的艺术家(作为“演讲者”)?selectize行为是我正在寻找的用户体验,我只是不知道如何通过报价单创建新的艺术家。

    2 回复  |  直到 6 年前
        1
  •  4
  •   e_a_o    6 年前

    如果必须使用selectize用户体验,则可能需要使用javascript通过Ajax创建艺术家/演讲者。与 selectize-rails gem , jquery-rails 还有一些javascript代码,您可以:

    1. 通过Ajax创建艺术家/演讲者,并将值和ID分配给Quotes表单输入- see demo

    2. 弹出与艺术家表单的模式,通过Ajax提交表单,并将值和ID分配给报价表单输入

    我试过用脚手架支撑这个 simple rails app 有了一个你想要实现的基本结构,向你展示了选项1的一个例子。我在自述文件中包含了安装说明和演示。

    所需的主要变更包括:

    宝石变化:

    添加 选择轨道 jquery轨 给你的宝石 Gemfile 然后运行bundle install。

    HTML表单更改:

    将selectize类添加到集合\u select input标记

    # /views/quotes/_form.html.erb
    
    <%= f.collection_select :artist_id, Artist.order(:name), :id, :name, {prompt: 'Select an artist'}, {class: 'selectize'} %>
    

    javascript更改:

    创造 /assets/javascript/quotes.js 并进行以下更改。

    # /assets/javascript/quotes.js
    
    $(document).on("turbolinks:load", function(){
      $(".selectize").selectize({
        create: function(input, callback) {
          $.post('/artists.json', { artist: { name: input } })
            .done(function(response){
              console.log(response)
              callback({value: response.id, text: response.name });
            })
        }
        });
    })
    

    修改您的 artists_controller

    修改 artists_controller#create action方法能够呈现JSON响应。

      # POST /artists
      # POST /artists.json
      def create
        @artist = Artist.new(artist_params)
    
        respond_to do |format|
          if @artist.save
            format.html { redirect_to @artist, notice: 'Artist was successfully created.' }
            format.json { render :show, status: :created, location: @artist }
          else
            format.html { render :new }
            format.json { render json: @artist.errors, status: :unprocessable_entity }
          end
        end
      end
    

    你也可以看 this GoRails video 了解如何实现选项2。

        2
  •  1
  •   matthewd    6 年前

    如果提供的是在缺少功能时创建,而唯一需要的值是选择器输入中的值,请考虑跳过 id 全部:

    class Quote < ApplicationRecord
      def speaker_name
        speaker&.name
      end
    
      def speaker_name=(name)
        self.speaker = name.presence && Artist.find_or_initialize_by(name: name)
      end
    

    在视图中:

    <%= f.label :speaker, 'Who said it?' %>
    <%= f.collection_select :speaker_name, Artist.order(:name), :name, :name, {prompt: 'Select an artist'}, {class: 'form-control select-artist'} %>
    

    (在 QuotesController#quote_params )

    然后,当您选择对输入进行格式化,允许输入新的值时,它应该可以正常工作。值得注意的是,这避免了通过Ajax急切地创建艺术家记录,如果有人键入一个条目,但从未提交表单,Ajax可以创建孤立的记录。