我很难弄清楚如何将Selectize.js与rails中的belongs_to关联。我想做这张照片:
我尝试使用accepts_nested_attributes
,但似乎不适用于belongs_to
关系。
我尝试进行类似railscast episode的自动完成关联。
我真正想做的是使用Selectize样式集合选择来创建“扬声器”关联(如果该关联已存在于数据库中),但是添加一个新的(如果该关联不存在的话)。 Selectize使我可以添加一个新记录,但是在将其传递给表单以在关联模型中创建新记录时遇到麻烦。
这是我的模特:
class Quote < ApplicationRecord
belongs_to :speaker, class_name: "Artist"
belongs_to :topic, class_name: "Artist"
end
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
我的表单:
<%= 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'} %>
控制器:
如何通过Quote.new表单和Selective-style集合select创建一个新的Artist(作为“发言人”)? Selectize行为是我想要的用户体验,我只是想不通如何通过Quote表单创建新的Artist。
答案 0 :(得分:4)
如果必须使用选择用户体验,则可能需要使用JavaScript通过ajax创建艺术家/扬声器。使用selectize-rails
gem,jquery-rails
和一些JavaScript代码,您可以:
通过ajax创建艺术家/扬声器,并将值和ID分配给引号形式的输入-see demo或
弹出带有艺术家表格的模式,通过ajax提交表格,并将值和id分配给引号形式输入
我已经尝试用您要实现的基本结构来简化此simple rails app,以向您展示选项1的示例。我在自述文件中包含了安装说明和演示。 / p>
所需的主要更改是:
将selectize-rails
和jquery-rails
宝石添加到Gemfile
中,然后运行捆绑安装。
将selectize类添加到collection_select输入标记中
# /views/quotes/_form.html.erb
<%= f.collection_select :artist_id, Artist.order(:name), :id, :name, {prompt: 'Select an artist'}, {class: 'selectize'} %>
创建/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
操作方法以能够呈现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。
答案 1 :(得分:1)
如果要提供缺少时创建功能,并且唯一需要的值是选择器输入中的值,请考虑完全跳过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
中有匹配的更改)
然后,当您对输入进行Selectify化时,允许输入新值,它应该可以正常工作。值得注意的是,这避免了通过AJAX急切创建艺术家记录,如果有人键入条目但从未提交表格,则AJAX可以创建孤儿。