路由到错误的网址

时间:2015-08-29 12:46:30

标签: ruby-on-rails ruby-on-rails-4 actionview

我正在

  

ActionView :: Template ::错误(没有路由匹配{:action =>“to_approve”,:controller =>“microposts”,:id => nil}缺少必需的键:[:id]):

     

没有路线匹配{:action =>“to_approve”,:controller =>“microposts”,   :id => nil}缺少必需的键:[:id]

但这没有任何意义,因为我正在路由到不同的路线

route.rb

  match '/microposts/:id/approve',  to: 'microposts#to_approve'  , via: [:get, :post], as: 'approve_micropost'
  match '/microposts/to_approve',  to: 'microposts#approve'  , via: :get

controller.rb

def show
  @tag = Tag.find(params[:id])
  @microposts = @tag.microposts
end

show.html.rb

<%= render @microposts %>

_micropost.html.rb - 以下是显示错误的行

  <% if is_an_admin? %>
    <%= link_to "Approve", approve_micropost_path(micropost.id) %>
  <% end %>

micropost_controller.rb

  def approve
    @microposts = Micropost.unapproved
  end

  def to_approve
    micropost = Micropost.unapproved_by_id(params[:id])
    if micropost.update_attributes(approved: true)
      flash[:success] = "Approved!"
    else
      flash[:error] = "Not approved!"
    end

    redirect_back_or microposts_to_approve_path
  end

micropost.rb

  default_scope { where(approved: true).order('microposts.created_at DESC')}

  def self.unapproved
    self.unscoped.all.where(approved: false).order('microposts.created_at DESC')
  end

  def self.unapproved_by_id(id = nil)
    self.unscoped.all.where(id: id)
  end

您可以看到它尝试使用microposts_to_approve_path创建:id,这显然不存在,但我写了approve_micropost_path

我错过了什么?

另外,在microposts_to_approve_path的路由中我允许[:get, :post]虽然我只想通过on_click事件(帖子?)允许访问to_approve方法,但没有查看它。我该怎么改写这个?

rake routes

       microposts POST     /microposts(.:format)             microposts#create
        micropost DELETE   /microposts/:id(.:format)         microposts#destroy
approve_micropost GET|POST /microposts/:id/approve(.:format) microposts#to_approve
microposts_to_approve GET      /microposts/to_approve(.:format)  microposts#approve

在错误页面上,参数:

Request

Parameters:

{"id"=>"4",
 "name"=>"tag name"}

解决方案

问题是因为我使用default_scope而不是我正在使用的对象不正常。

修复前

@microposts = @tag.microposts        #@microposts is CollectionProxy

之后

@microposts = @tag.microposts.all    #@microposts is AssociationRelation

一旦我改为.all,问题就解决了。

顺便说一句,这是一个错误吗?我的意见default_scope不应该改变默认行为..

1 个答案:

答案 0 :(得分:0)

如果您希望它仅回复帖子,请尝试更改您的链接以使用方法&#39;发布&#39;。

<% if is_an_admin? %>
  <%= link_to "Approve", approve_micropost_path(micropost.id), method: :post %>
<% end %>

相反,如果你想让它在get上路由到微博#to_approve,那么让你的链接明确地调用get。

<% if is_an_admin? %>
  <%= link_to "Approve", approve_micropost_path(micropost.id), method: :get %>
<% end %>

然后你应该使用POST路由到微博#to_approve。但是,由于您允许执行任一操作,请确保在to_approve操作中,您必须检查请求类型。如:

#microposts controller

def to_approve
  if request.post?
    # Do post related things
  else
    # Do get related things
  end
end

使用to_approve网址上的approve操作,并使用approve网址上的to_approve操作的旁注***令人困惑,您可能会忘记原因 - 你在6个月后查看代码时做了什么。

修改

另一种方法可能是拆分路线,这样您就不会在控制器中调用if语句。

route.rb

post '/microposts/:id/approve',  to: 'microposts#approve', as: 'approve_micropost'
get '/microposts/:id/to_approval', to: 'microposts#to_approve', as: 'micropost_approvals'
resources :microposts