【问题标题】:find_or_create_by_name with has_many :throughfind_or_create_by_name 和 has_many :through
【发布时间】:2011-03-12 01:23:05
【问题描述】:

艺术家有很多活动。活动有许多艺术家。这两个模型之间的连接称为 Performances。

我正在尝试将艺术家与事件添加/编辑页面上的事件相关联。我希望仅当艺术家不存在时才能够添加它,并且无论如何都要创建连接(性能)。艺术家只能与事件关联一次。

有人建议我使用 find_or_create_by_name 而不是 accept_nested_attributes_for。

我正在遵循 Railscasts #102 的 Auto-Complete 指令,它说要使用虚拟属性。我什至还没有进入自动完成部分,只是试图让 find_or_create_by_name 工作。

我在活动编辑和新页面上收到“未定义的方法 `artist_name' for #”。在 Railscast 中,Ryan 在将方法添加到模型之前获得了一个未定义的方法。但我在模型中有方法。

不知道该怎么办。

事件.rb

validates_presence_of :name, :location
validates_uniqueness_of :name

validates_associated :performances

has_many :performances, :dependent => :delete_all
has_many :artists, :through => :performances

#accepts_nested_attributes_for :artists, :reject_if => proc {|a| a['name'].blank?}, :allow_destroy => true

def artist_name
  artist.name if artist
end

def artist_name=(name)
  self.artist = Artist.find_by_name(name) unless name.blank?
end

艺术家.rb

validates_presence_of :name

has_many :mixes  

has_many :performances, :dependent => :delete_all
has_many :events, :through => :performances

性能.rb

belongs_to :artist
belongs_to :event

events_controller.rb

def create
  @event = Event.new(params[:event])

  respond_to do |format|
    if @event.save
      flash[:notice] = 'Event was successfully created.'
      format.html { redirect_to(admin_events_url) }
      format.xml  { render :xml => @event, :status => :created, :location => @event }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @event.errors, :status => :unprocessable_entity }
    end
  end
end

_form.html.erb

<% form_for([:admin,@event]) do |f| %>
<p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
</p>
<p>
    <%= f.label :location %><br/>
    <%= f.text_field :location %>
</p>
<p>
    <%= f.label :date %><br />
    <%= f.date_select :date %>
</p>
<p>
    <%= f.label :description %><br />
    <%= f.text_area :description %>
</p>
<% f.fields_for :artists do |builder| %>
    <%= render 'artist_fields', :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add Artist", f, :artists %></p>
<p>
    <%= f.submit 'Submit' %> <%= link_to 'Cancel', admin_events_path %>
</p>
<% end %>

_artist_fields.html.erb

<p class="fields">   
<%= f.label :artist_name, "Artist"%><br/>
<%= f.text_field :artist_name %>
<%= link_to_remove_fields "remove", f %>
</p>

【问题讨论】:

  • 从您为artist_fields.html.erb 提供的代码片段中不清楚您是如何设置表单构建器实例(由 f 表示)。你应该有类似&lt;% form_for @event do |f| %&gt; ... &lt;% end %&gt; 的东西来分隔这些。对吗?
  • _artist_fields.html.rb 是部分的。 form_for 位于 _form.html.rb

标签: ruby-on-rails validation autocomplete


【解决方案1】:

我个人会回到accepts_nested_attributes_for,ryan bates方法在嵌套属性之前的日子里。

在您的控制器中执行以下操作:

def new
  @event = Event.find params[:id]
  @artist = @event.artists.build


def edit
  @event = Event.find params[:event_id]
  @artist = @event.artists.find params[:user_id]

在视图中

...
<% f.fields_for :artists, @artist do |builder| %>    
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多