Reputation: 15
I have a view which lists all my comparisons
<% @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 %>
Up to now, all is going well : title, description and id are displayed for each comparison.
I tried to add a Show link :
<% @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 %>
But now, when I load index.html.erb I have this error :
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]
I don't understand why...
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
By the way, as you can see, in create action, I have not been able to use a redirect_to
. But render :show
works : the show.html.erb view is loaded.
Any risks to use render
rather 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"}
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
Thanks in advance for your help.
Upvotes: 0
Views: 875
Reputation: 15
Previous answers made me realize I had a routing issue with i18n : locale parameter was not considered in urls building.
In application_controller.rb I still have
before_action :set_locale
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
I add this second method which automatically add the locale parameter to urls
def default_url_options
{ locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
end
Now, it works fine.
Thanks for your help.
Upvotes: 1
Reputation: 3057
It seems to me using :shallow_path would be the answer. From the documentation.
The :path, :as, :module, :shallow_path and :shallow_prefix options all default to the name of the namespace.
I think this will remove (/:locale) from the raked routes
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
Upvotes: 0
Reputation: 1601
Alternatively you can use like this:
<% @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 %>
Upvotes: 0
Reputation: 1323
Seeing from your routes files, it looks to me that to construct a route, you need two parameters - locale
and id
. Since you are using comparison_path(comparison)
, rails is assuming that the first parameter you are passing refers to locale.
To construct a correct route, use a cleaner way to construct a route - like this:
comparison_path(locale: 'en', id: comparison.id)
Upvotes: 1