控制器方法#show 被调用

Controller method #show getting called

我的 #index 视图中有一个 link:

<%= link_to 'Export Calendar (ICS)', { controller: :tickets, action: :ics_export, format: :ics }, class: "class-needed right" %>

routes.rb 与此相关:

resources :tickets
get 'tickets/calendar' => 'tickets#ics_export'
post 'tickets' => 'tickets#index'
patch 'tickets/:id/close' => 'tickets#close', as: 'close_ticket'
post 'tickets/:id' => 'ticket_comments#create'

我的 TicketsController 属于:

before_action :set_ticket, only: [:show, :edit, :destroy, :update, :close]

def show
  @ticket_comment = TicketComment.new
end

def ics_export
  tickets = Ticket.all
  respond_to do |format|
    format.html
    format.ics do
      cal = Icalendar::Calendar.new
      tickets.each do |ticket|
        event = Icalendar::Event.new
        event.dtstart = ticket.start
        event.description = ticket.summary
        cal.add_event(event)
      end
      cal.publish
      render :text =>  cal.to_ical
    end
  end
end

private
def set_ticket
  @ticket = Ticket.find(params[:id])
end

当我单击 link 时,它会将我带到 /tickets/calendar.ics,这是正确的,但我收到以下错误:

ActiveRecord::RecordNotFound in TicketsController#show

Couldn't find Ticket with 'id'=calendar

Extracted source (around line #83):

 private
 def set_ticket
   @ticket = Ticket.find(params[:id])
 end

@ticket = Ticket.find(params[:id]) 突出显示。这是有道理的,它无法调用 ID 为 calendar.

的票证

请求有参数:

{"id"=>"calendar", "format"=>"ics"}

如何修复此错误?为什么叫表演动作?

规范Rails Routing from the Outside In中有一个脚注大意为:

Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action's route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.

如评论所述,解决方法是在 resources :tickets 之前指定 get 'tickets/calendar' => ...。如果路由的顺序有问题,您可以 运行 rake routes,据我所知,它应该按照检查的顺序呈现您的路由。