我跟随了Ryan Bate关于令牌输入的Railscast,它完全适用于我的发布'等级使用:
<%= f.text_field :artist_tokens, "data-pre" => @release.artists.map(&:attributes).to_json, :class => "text" %
根据发布,我有跟踪&#39;并希望能够在轨道级别修改和改变艺术家。使用上面我可以使它继承&#39;发布级别的艺术家和这似乎适用于新方法和初始设置,但在编辑它显然拉回发布级别的艺术家,如果提交它命中,那么所有的轨道级艺术家都被覆盖。
我试图这样做:
<% if params[:action] == "edit" %>
<%= f.text_field :artist_tokens, "data-pre" => @track.artists.map(&:attributes).to_json, :class => "text" %>
<% else %>
<%= f.text_field :artist_tokens, "data-pre" => @release.artists.map(&:attributes).to_json, :class => "track_artist_tokens" %>
<% end %>
但是我得到了一个未定义的方法&#39;艺术家&#39;在@ track.artists.map
我的模型如下:
class Release < ActiveRecord::Base
has_many :artist_releases
has_many :artists, :through => :artist_releases
attr_reader :artist_tokens
def artist_tokens=(ids)
self.artist_ids = ids.split(",")
end
has_many :releases_tracks, :dependent => :destroy
has_many :tracks, :through => :releases_tracks
accepts_nested_attributes_for :tracks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => :true
has_many :artists_tracks
end
class Artist < ActiveRecord::Base
has_many :artist_releases
has_many :releases, :through => :artist_releases
has_many :artists_tracks
has_many :tracks, :through => :artists_tracks
end
class Track < ActiveRecord::Base
has_many :releases_tracks, :dependent => :destroy
has_many :releases, :through => :releases_tracks
has_many :artists_tracks
has_many :artists, :through => :artists_tracks
attr_reader :artist_tokens
def artist_tokens=(ids)
self.artist_ids = ids.split(",")
end
end
class ArtistsTrack < ActiveRecord::Base
belongs_to :artist
belongs_to :release
belongs_to :track
end
class ReleasesTrack < ActiveRecord::Base
belongs_to :release
belongs_to :track
acts_as_list
end
有人可以帮忙吗?
更新
发布控制器跟踪方法:
def tracks
@release = Release.find(params[:id])
@track = @release.tracks.find(:all)
respond_to do |format|
format.html # tracks.html.erb
end
end
tracks.html.erb有:
<%= form_for @release do |f| %>
<%= f.fields_for :tracks do |builder| %>
<%= render 'track_fields', :f => builder %>
<% end %>
<% end %>
_track_fields.html.erb partial(为清晰起见,部分HTML被剥离)
<td class="label">Title:</td>
<td class="field"><%= f.text_field :name, :class => "text" %></td>
<td class="label">Artists:</td>
<td class="field">
<% @track.each do |track| %>
<%= f.text_field :artist_tokens, "data-pre" => track.artists.map(&:attributes).to_json, :class => "track_artist_tokens" %>
<% end %>
<p><%= link_to 'Add new artist', new_artist_path, :remote => true %></p>
<td class="label">Version:</td>
<td class="field"><%= f.text_field :version, :class => "text" %></td>
<td class="label">ISRC:</td>
<td class="field"><%= f.text_field :isrc, :class => "text" %></td>
<td class="label">Remove:</td>
<td class="field"><%= f.check_box :_destroy %></td>
答案 0 :(得分:1)
在show
操作中@track
是一个track
对象。在customer
操作中,它是track
个对象的集合。所以要么你必须遍历它们:
<% @track.each do |track| %>
<%= f.text_field :artist_tokens, "data-pre" => track.artists.map(&:attributes).to_json, :class => "text" %>
<% end %>
或者获取该集合的第一个track
:
<%= f.text_field :artist_tokens, "data-pre" => @track.first.artists.map(&:attributes).to_json, :class => "text" %>