Why Rails dont recognize route - ruby-on-rails

I have in routes.rb
get '/cities/:city/:section' => 'cities#show', as: 'city_section_slug'
get '/cities/:city/:section/:subsection' => 'cities#show', as: 'city_subsection_slug', :constraints => { :subsection => /[^\/]*/ }
And rake show these routes
city_section_slug GET (/:locale)/cities/:city_id/:section(.:format) cities#show {:locale=>/ru|en/}
city_subsection_slug GET (/:locale)/cities/:city_id/:section/:subsection(.:format) cities#show {:subsection=>/[^\/]*/, :locale=>/ru|en/}
But when I try create a link:
= link_to city_subsection_slug_path(#city,section.alias, subsection.alias)
Iv got such error:
ActionController::RoutingError (No route matches {:controller=>"cities", :action=>"show", :locale=>:ru, :city=>#<City id: 42, name: "City">, :section=>"events", :subsection=>"sobytiya/ya-ochevidets"}):
Any ideas where I am wrong?

The reason is your constraint on subsection param. You specified that it can be anything as long as it does not contain / character. Your subsection does conatin it hence the error. If you want to allow / character, then do:
get '/cities/:city/:section/:subsection' => 'cities#show',
as: 'city_subsection_slug',
constraints: { :subsection => /^[a-z0-9_\/]+$/ }
Eventually, you can use glob param:
get '/cities/:city/:section/*subsection' => 'cities#show',
as: 'city_subsection_slug',

#config/routes.rb
resources :cities, only: [] do
get ":section", action: :show, as: :city_section_slug #-> url.com/cities/:city_id/:section
get ":section/*subsection", action: :show, as: :city_subsection_slug #-> url.com/cities/:city_id/:section/:subsection
end
The corresponding links:
<%= link_to "x", city_section_slug_path(#city, section.alias) %>
<%= link_to "x", city_subsection_slug_path(#city, section.alias, subsection.alias) %>
Wildcard
If you're expecting to send sobytiya/ya-ochevidets to your subsection path, you'll be best using a wildcard route

Related

Why is my route ignored for one below it?

I have code that specifies the following routes in my routes.rb:
concern :searchable do
get "search(/:query)", controller: "search", action: :show, as: "search"
end
scope module: 'custom_domains', as: "custom_domain" do
root to: "pages#show", id: "index"
concerns :searchable
get '/:id' => "pages#show", as: "page"
match "*path" => "redirects#show", via: [ :get ], as: "redirect"
end
/
/search(/:query)(.:format)
/:id(.:format)
/*path(.:format)
When I try to visit /search, the route is skipped and catch all *path matches the route. I'm stumped. Routes are defined top to bottom and match in that order, so I would think that /search would be correct match. Do you know why this isn't the case?

custom route in rails 4 not working

I've created custom routes to route to News model
resources :news, only: [:index] do
collection do
get 'page/:page', action: :index
end
end
get "news/:id(/p/:p)", to: 'news#show', as: 'news'
generate url like this
http://localhost:3000/news/4/page/2 index.html.erb is right
and show.html.erb
<%= link_to 'news', news_path(#news, '2')%>
I hope generate url http://localhost:3000/news/4/p/2
but generate http://localhost:3000/news/4?p=2
I think you've got a route conflict, change this:
get "news/:id(/p/:p)", to: 'news#show', as: 'news'
to this:
get "news/:id(/p/:p)", to: 'news#show', as: 'news_page'
and the use this link:
<%= link_to 'News', news_page_path(#news, '2')%>

how to remove action and controller from url in rails link_to

Here is my link_to
<%= link_to sub_category.name, controller: :posts, action: :product, id: "#{sub_category.slug}-#{sub_category.id}" %>
Which is pointing to the url
http://localhost:3000/posts/product/fifith-category-s-sub-category-2
I need the url as follows
http://localhost:3000/fifith-category-s-sub-category-2
How can i do it.
my route.rb
resources :posts
match ':controller(/:action(/:id))(.:format)', via: [:get,:post]
what #MarekLipka suggests is correct but defining your routes like this will take up all the single level namespace in your app i.e. "/anything" will route by default to posts#product.
I recommended using some form of identifier to figure out which routes should go to posts#product. What will work for you depends on why you want to do this. Couple of options are:
Use a short namespace:
scope '/pp' do
get ':id', to: 'posts#product
end
# "/pp/:id" routes to 'posts/product'
# pp is a random short name I picked, it could be anything
# link
<%= link_to sub_category.name, "pp/#{sub_category.slug}-#{sub_category.id}" %>
Use a constraint:
get ':id', to: 'posts#product`, constraints: { :id => /sub\-category/ }
# only id's with 'sub-cateogry' route to 'posts/product'
# link (assuming that sub_category.slug has 'sub-category' words in it)
<%= link_to sub_category.name, "#{sub_category.slug}-#{sub_category.id}" %>
If you want path /:id match your posts#product, you should have something like this in your routes:
resources :posts
match ':id', to: 'posts#product`, via: :get
match ':controller(/:action(/:id))(.:format)', via: [:get, :post]

ActiveRecord::RecordNotFound in PostsController#show clicking a link

<li><%= link_to('More Commented', posts_morecommented_path) %></li>
Error
ActiveRecord::RecordNotFound in PostsController#show
Couldn't find Post with id=morecommented
Request
Parameters:
{"id"=>"morecommented"}
Where am I doing the mistake?
postscontroller#show action
def show    #post = Post.find(params[:id])    ...   end
morecommented.html.erb
<% #moreCommented.each do |t| %>
<%= link_to t.title, :controller => '/posts', :action => 'show', :id => t.id %><br/>
<% end %>
rake routes
post GET /posts/:id(.:format) {:action=>"show", :controller=>"posts"}
....
posts_morecommented /posts/morecommented(.:format) {:controller=>"posts", :action=>"morecommented"}
routes.rb:
resources :posts
match "posts/:id/categ" => "posts#categ"
match "posts/:id/tag_posts" => "posts#tag_posts"
match "posts/searcharchive" => "posts#searcharchive"
match "posts/morecommented" => "posts#morecommented"
move the match before the resources call
match "posts/morecommented" => "posts#morecommented"
resources :posts
Alternatively you can do
resources :posts do
get :morecommented, on: :collection
end
Your problem is inside your routes.rb file since routes are matched from the top to the bottom action posts/morecommented matches posts/:id action with params[:id] equal to morecommented One solution as Gerry mentioned is to change order and move the match "posts/morecommented" => "posts#morecommented" before the call resources :posts in your routes.rb file the other one is to set requirements on :id in your posts/:id route.

How do I get my app to go to this custom view?

I have this custom action in my videos controller:
def upvoted_songs
#votes = current_user.videos_votes.where("value = 1")
#videos = #votes.videos.page(params[:page]).per(15)
end
this is my routes:
resources :videos do
member do
put 'topic_update'
get 'upvoted_songs'
end
end
And this link in my videos index view:
<%= link_to "Upvoted Songs", videos_path, :action => "upvoted_songs", :class => "upvoted_songs chosen_home_option" %>
and a view file called videos/upvoted_songs.html.erb.
Why doesn't the link direct to the upvoted_songs.html.erb view but rather stay on the video index view?
UPDATE:
These is my routes.rb:
root :to => "videos#index"
resources :video_votes
resources :videos do
resources :comments
member do
put 'topic_update', :on => :member
get 'upvoted_songs', :on => :collection, :as => 'upvoted'
end
end
resources :comment_titles
resources :users
resources :profiles
resources :genres
resources :topics
resources :topicables
resource :session
I initially get this error:
ArgumentError
can't use member outside resource(s) scope
Then after refreshing the page, I get this error:
ActionController::RoutingError in Videos#index
Showing /rubyprograms/dreamstill/app/views/videos/_video.html.erb where line #22 raised:
No route matches {:action=>"show", :id=>#<Video id: 485, title: "I'm Ready For You", description: nil, embed_code: nil, thumbnail_url: nil, released: nil, user_id: 57, created_at: "2011-04-02 08:47:36", updated_at: "2011-04-09 22:42:48", video_url: "http://www.youtube.com/watch?v=wy86KNtOjVg", video_votes_count: 0, vote_sum: 3, rank_sum: 28927.724512>, :controller=>"videos"}
22: <%= link_to video.title, video_path(video), :class => "normal" %>
To see what routes are available for use in your app use rake routes on the command line in the root directory of the app. You should see a line that refers to upvoted_songs.
Then use it like so:
<%= link_to "Upvoted Songs", upvoted_songs_video_path(video), :class => "upvoted_songs chosen_home_option" %>
Since you have it has a member route the url helper will take a video object (or id) and generate a url that looks something like: /videos/7/upvoted_songs
However, your code suggests that you might be doing something that does not rely on a single video object, and wouldn't need that in the URL either. So you would want to change that route from a member route to a collection route. The URL would then end up looking something like /videos/upvoted_songs and you wouldn't be passing it a video object.
Hope this helps :)
PART 2
Remove the member block:
resources :videos do
resources :comments
put 'topic_update', :on => :member
get 'upvoted_songs', :on => :collection, :as => 'upvoted'
end
You are linking to videos_path, which is a helper for "videos#index".
As ctcherry explained, your current route is using a member route and not a collection. The following is more what you're looking for:
resources :videos do
put 'topic_update', :on => :member
get 'upvoted_songs', :on => :collection, :as => 'upvoted'
end
Then you can use upvoted_videos_path in place of just videos_path.
You don't have an id. Do a rake routes | grep upvoted and see what your route should look like.
it's probably something like upvoted_songs_video_path(video)

Resources