Rails 5 - NoMethod错误 - 未定义的方法

时间:2016-10-15 08:19:46

标签: ruby-on-rails ruby-on-rails-5

在我正在构建的用于学习Rails的应用程序中,我在模型" TAG"之间存在多态关系。和模型"注释"和"文件"。与文章和评论模型类似。

创建和销毁标签正在发挥作用。现在,我想更新标签并遇到一个我不明白的无方法错误。尝试了许多替代方案(例如,使用<%= link_to tag.content, [object, tag]...形式的<%= simple_form_for object.tag ...

使用以下方式调用表单:

<% object.tags.each do |tag| %>
        <% unless tag.content.blank? %>
        <tr>
            <td><%= link_to tag.content, @tag, method: :patch %></td>

这是标签控制器:

class TagsController < ApplicationController

def index

end

def create
  tagable = detect_tagable
  tagable.tags.create(tag_params)
  redirect_to tagable_path(tagable)
end

def update
  tagable = detect_tagable
  @tag = tagable.tags.find(params[:id]) 
  @tag.save
  render '_tag_update'
end

def destroy
  tagable = detect_tagable
  @tag = tagable.tags.find(params[:id])
  @tag.destroy
  redirect_to tagable_path(tagable)
end

private

  def tagable_path(tagable)
    case tagable
    when Document
      document_path(tagable)
    when Annotation
      annotate_path(tagable)
    else
      fail 'Unknown tagable'
    end
  end

  def detect_tagable
    if params[:annotation_id]
      Annotation.find(params[:annotation_id])
    elsif params[:document_id]
      Document.find(params[:document_id])
    else
      fail 'Tagable not found'
    end
  end

  def tag_params
    params.require(:tag).permit(:content, :location, :tagtype_id,annotation_attributes: { annotation_ids:[] }, document_attributes: { document_ids:[] })
  end

end

它使用正确的参数(注释标识和标记ID)呈现正确的格式_tag_update.html.erb,但却抛出错误:

<%= simple_form_for @tag, html: { class: 'form-vertical', multipart: true },

完整错误

  

标签#update中的NoMethodError   显示/Users/Dimitri/Documents/AppDev/shine/app/views/tags/_tag_update.html.erb,其中第1行引发:   未定义的方法`tag_path&#39;对于#&lt;#:0x007fc2aede9d88&gt;   你的意思是? tagtype_path   提取的来源(第1行):   1   2   3   4   五   6
  &lt;%= simple_form_for @tag,html:{class:&#39; form-vertical&#39;,multipart:true},       wrapper :: horizo​​ntal_form,       wrapper_mappings:{       check_boxes :: horizo​​ntal_radio_and_checkboxes,       radio_buttons :: horizo​​ntal_radio_and_checkboxes,       file :: horizo​​ntal_file_input,   Rails.root:/ Users / Dimitri / Documents / AppDev / shine

应用程序跟踪|框架跟踪|完整跟踪:

  

app / views / tags / _tag_update.html.erb:1:_app_views_tags__tag_update_html_erb___1949489846228898836_70237067101380' app/controllers/tags_controller.rb:17:in更新&#39;   请求

参数:

{"_method"=>"patch", "authenticity_token"=>"LhqKjyjbYdznMvx+GjsIL0phwT8pRTtanooKU6Xt4hHaPRFMmZJmZVm7GGZa8iaWxN1MIfm7xHwwhSSrSBoO/g==", "annotation_id"=>"6", "id"=>"24"}

1 个答案:

答案 0 :(得分:1)

当您将记录传递给link_to时,form_forredirect_to rails会将记录传递给polymorphic route helpers(请注意,这与多态关联无关)。

要生成到嵌套资源的路径,您需要传递父记录和子记录:

simple_form_for( [@tag.taggable, @tag],  # ...

link_to( @tag.content, [@tag.taggable, @tag] )

redirect_to( [@tag.taggable, @tag] )

您无需执行控制器:

def tagable_path(tagable)
  case tagable
  when Document
    document_path(tagable)
  when Annotation
    annotate_path(tagable)
  else
    fail 'Unknown tagable'
  end
end

只需redirect_to taggable并且rails将使用聪明的约定为您找出路线。

嵌套并不总是好的。

成员路由不需要嵌套。由于每个记录都由唯一的ID访问,因此您可以取消成员路由:

# avoids duplication
concern :taggable do
  resources :tags, only: [:new, :index, :create]
end

# generates GET|PATCH|DELETE /tags/:id and /tags/:id/edit
resources :tags, only: [:show, :edit, :destroy, :update]

resources :documents, concerns: :taggable
resources :annotations, concerns: :taggable

resources :annotations, shallow: true选项提供了类似的结果。

这意味着您可以redirect_to(@tag)link_to('Delete tag', @tag, method: :delete )