Я использую jQuery Tokeninput, как показано в этом документе Railscast. Я хотел бы объединить эти функции в вложенной форме, но получает ошибкуИспользование jQuery Tokeninput в частичной вложенной форме
undefined method `artists' for #<SimpleForm::FormBuilder:0x007febe0883988>
По какой-то причине его не признающий параметра следа в моей форме строителе, который мешает мне ухватить альбомы у меня есть на записи ,
<div class="input">
<%= f.input :artist_tokens, label: 'Featured Artists', input_html: {"data-pre" => f.artists.map(&:attributes).to_json} %>
</div>
Имейте в виду, что это работает в моей track
форме, но только не в моей album
форме, так как его вложенным. Что мне делать, чтобы заставить это работать?
class ArtistsController < ApplicationController
def index
@artists = Artist.order(:name)
respond_to do |format|
format.html
format.json {render json: @artists.tokens(params[:q])}
end
end
end
Модели
class Artist < ActiveRecord::Base
has_many :album_ownerships
has_many :albums, through: :album_ownerships
has_many :featured_artists
has_many :tracks, through: :featured_artists
def self.tokens(query)
artists = where("name like ?", "%#{query}%")
if artists.empty?
[{id: "<<<#{query}>>>", name: "Add New Artist: \"#{query}\""}]
else
artists
end
end
def self.ids_from_tokens(tokens)
tokens.gsub!(/<<<(.+?)>>>/) {create!(name: $1).id}
tokens.split(',')
end
end
class Albums < ActiveRecord::Base
attr_reader :artist_tokens
accepts_nested_attributes_for :tracks, :reject_if => :all_blank, :allow_destroy => true
has_many :albums_ownerships
has_many :artists, through: :albums_ownerships
def artist_tokens=(ids)
self.artist_ids = Artist.ids_from_tokens(ids)
end
end
class Track < ActiveRecord::Base
attr_reader :artist_tokens
belongs_to :album
has_many :featured_artists
has_many :artists, through: :featured_artists
def artist_tokens=(ids)
self.artist_ids = Artist.ids_from_tokens(ids)
end
end
class AlbumOwnership < ActiveRecord::Base
belongs_to :artist
belongs_to :album
end
class FeaturedArtist < ActiveRecord::Base
belongs_to :artist
belongs_to :track
end
Альбом Форма
<%= simple_form_for(@album) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<h1>Tracks</h1>
<%= f.simple_fields_for :tracks do |track| %>
<%= render 'track_fields', :f => track %>
<% end %>
<div id='links'>
<%= link_to_add_association 'Add Field', f, :tracks %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Трек Частичное
<div class="field">
<%= f.input :name %><br>
</div>
<div class="input">
<%= f.input :artist_tokens, label: 'Featured Artists', input_html: {"data-pre" => f.artists.map(&:attributes).to_json} %>
</div>
JS
$(function() {
$('#track_artist_tokens').tokenInput('/artists.json', {
prePopulate: $("#track_artist_tokens").data("pre"),
theme: 'facebook',
resultsLimit: 5
});
});
UPDATE
Как отметил nathanvda, мне нужно использовать f.object
для того, чтобы художники, которые будут признаны. Так что в моей частичной теперь у меня есть:
<%= f.input :artist_tokens, label: 'Featured Artists', input_html: {"data-pre" => f.object.artists.map(&:attributes).to_json, class: 'test_class'} %>
В моих JS я также необходимы для перед вызовом метода маркера ввода/после вставки:
$(function() {
$('.test_class').tokenInput('/artists.json', {
prePopulate: $(".test_class").data("pre"),
theme: 'facebook',
resultsLimit: 5
});
$('form').bind('cocoon:after-insert', function(e, inserted_item) {
inserted_item.find('.test_class').tokenInput('/artists.json', {
prePopulate: $(".test_class").data("pre"),
theme: 'facebook',
resultsLimit: 5
});
});
});
Единственный оставшийся вопрос у меня есть, tracks_attributes
не сохраняются. Я столкнулся с проблемой, подобной этому в прошлом в этом post, но два основных отличия - это второй уровень вложенности и что я использовал таблицу соединений в моей вложенной форме. Я не совсем уверен, что если бы какой-либо из этого кода переводил, но я считаю, что это наиболее вероятная проблема. Что касается разрешенных параметров моего albums_controller
, то вот как они выглядят.
def album_params
params.require(:album).permit(:name, :artist_tokens, tracks_attributes: [:id, :name, :_destroy, :track_id])
end
Не могли бы вы узнать, где я это положил? Прямо сейчас у меня это в части "_track_fields", но получаю ошибку: 'uninitialized constant Track :: FeaturedArtist' с этим кодом:' <% = f.input: artist_tokens, label: 'Featured Artists', input_html: {"data-pre" => f.object.artists.map (&: attributes) .to_json}%> ' –
В вашей модели вы пишете, что художники связаны через признанных художников, и это модель, которая не найдена. Можете ли вы проверить, что track.artists работает вообще? Вы также не использовали определение для featured_artists. – nathanvda
К сожалению, нет. Я получаю ошибку: 'undefined local variable или method 'track' для # <#: 0x007fdd97832d28>'. 'FeaturedArtist' служит только как таблица соединений между' artist' и 'tracks'. –