没有路线匹配{:action =>“show”

时间:2015-07-04 18:57:06

标签: ruby-on-rails

我有一个列出所有比较的视图

index.html.erb

<% @comparisons.each do |comparison| %>
 <div class="col-xs-6 col-sm-4 col-md3">
  <p><%= comparison.title %></p>
  <p><%= comparison.id %></p>
  <p><%= comparison.description %></p>
 </div>
<% end %>

到目前为止,一切进展顺利:每次比较都会显示标题,说明和ID。

我尝试添加一个Show链接:

<% @comparisons.each do |comparison| %>
 <div class="col-xs-6 col-sm-4 col-md3">
  <p><%= comparison.title %></p>
  <p><%= comparison.id %></p>
  <p><%= comparison.description %></p>
  <p><%= link_to 'Show', comparison_path(comparison) %></p>
 </div>
<% end %>

但现在,当我加载index.html.erb时出现此错误:

No route matches {:action=>"show", :controller=>"comparisons", :format=>nil, :id=>nil, :locale=>#<Comparison id: 1, title: "coucou", description: "", created_at: "2015-07-04 10:33:47", updated_at: "2015-07-04 10:33:47", user_id: 1>} missing required keys: [:id]

我不明白为什么......

comparisons_controller.rb

class ComparisonsController < ApplicationController
 before_action :set_comparison, only: [ :show ]
 skip_before_action :authenticate_user!, only: [ :index, :show ]

 def index
  @comparisons = policy_scope(Comparison)
 end 

 def show
 end

 def new
  @comparison = current_user.comparisons.new
  authorize @comparison
 end

 def create
  @comparison = current_user.comparisons.new(comparison_params)
  authorize @comparison

  if @comparison.save
   # redirect_to comparison_path(@comparison)
   # redirect_to @comparison
   render :show
  else
   render :new
  end
 end

 private

 def set_comparison
  @comparison = Comparison.find(params[:id])
  authorize @comparison
 end

 def comparison_params
  params.require(:comparison).permit(:title, :description, :user_id)
 end
end

顺便提一下,正如您所看到的,在创建操作中,我无法使用redirect_to。但render :show有效:show.html.erb视图已加载。 使用render而非redirect_to的任何风险?

我的路线

                  Prefix Verb   URI Pattern                          Controller#Action
        new_user_session GET    /users/sign_in(.:format)               devise/sessions#new
            user_session POST   /users/sign_in(.:format)             devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)            devise/sessions#destroy
           user_password POST   /users/password(.:format)            devise/passwords#create
       new_user_password GET    /users/password/new(.:format)        devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format)       devise/passwords#edit
                         PATCH  /users/password(.:format)            devise/passwords#update
                         PUT    /users/password(.:format)            devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)              devise/registrations#cancel
       user_registration POST   /users(.:format)                     devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)             devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)                devise/registrations#edit
                         PATCH  /users(.:format)                     devise/registrations#update
                         PUT    /users(.:format)                     devise/registrations#update
                         DELETE /users(.:format)                     devise/registrations#destroy
                    page GET    (/:locale)/pages/:id                 high_voltage/pages#show {:locale=>/fr/}
             comparisons GET    (/:locale)/comparisons(.:format)     comparisons#index {:locale=>/fr/}
                         POST   (/:locale)/comparisons(.:format)     comparisons#create {:locale=>/fr/}
          new_comparison GET    (/:locale)/comparisons/new(.:format) comparisons#new {:locale=>/fr/}
              comparison GET    (/:locale)/comparisons/:id(.:format) comparisons#show {:locale=>/fr/}
                    home GET    /home(.:format)                      redirect(301, /)
                    root GET    /                                    high_voltage/pages#show {:id=>"home"}

的routes.rb

Rails.application.routes.draw do
 devise_for :users

 scope '(:locale)', locale: /fr/ do
  get 'pages/:id' => 'high_voltage/pages#show', :as => :page, :format => false
  resources :comparisons, only: [ :index, :show, :new, :create ]
 end
end

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

从您的路线文件中看,我认为要构建路线,您需要两个参数 - localeid。由于您使用的是comparison_path(comparison),因此rails假定您传递的第一个参数是指区域设置。

要构建正确的路线,请使用更简洁的方法构建路线 - 如下所示:

comparison_path(locale: 'en', id: comparison.id)

答案 1 :(得分:0)

或者您也可以这样使用:

<% @comparisons.each do |comparison| %>
  <div class="col-xs-6 col-sm-4 col-md3">
    <p><%= comparison.title %></p>
    <p><%= comparison.id %></p>
    <p><%= comparison.description %></p>
    <p><%= link_to 'Show', comparison %></p>
  </div>
<% end %>

答案 2 :(得分:0)

在我看来,使用:shallow_path就是答案。来自documentation

  

:path,:as,:module,:shallow_path和:shallow_prefix选项都默认为命名空间的名称。

我认为这会从raked路线中删除(/:locale)

 scope '(:locale)', locale: /fr/, :shallow_path => '(:locale)' do
  get 'pages/:id' => 'high_voltage/pages#show', :as => :page, :format => false
  resources :comparisons, only: [ :index, :show, :new, :create ]
 end

答案 3 :(得分:0)

之前的回答让我意识到我遇到了i18n的路由问题:在网址建设中没有考虑locale参数。

在application_controller.rb中我还有

def default_url_options
 { locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
end

我添加第二个方法,自动将locale参数添加到urls

ViewController.h

@interface ViewController : UIViewController
@property(nonatomic, weak)IBOutlet UICollectionView *my_collectionview;
@end

ViewController.m

@interface ViewController ()
@end

@implementation ViewController
@synthesize my_collectionview;


- (void)viewDidLoad {
[super viewDidLoad];

}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return 1;
}


-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 9;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell" forIndexPath:indexPath];

return cell;
}

CollectionViewCell.h

@interface CollectionViewCell : UICollectionViewCell
@property(nonatomic, weak) IBOutlet UIImageView *temp_imgview;
@end


CollectionViewCell.m

-(void)awakeFromNib{
    [temp_imgview.layer setCornerRadius:self.temp_imgview.frame.size.width/2];
    temp_imgview.layer.borderWidth=0.5;
    temp_imgview.layer.masksToBounds = YES;
    temp_imgview.clipsToBounds=YES;
}

现在,它运作正常。

感谢您的帮助。