Same url format in different controllers with ruby on rails - ruby-on-rails

I am having difficulties with routings in ruby on rails. I have same url format in different controllers and I am trying to send params to site controller but it goes to pages controller instead. Any help?
Route.rb
resources :sites, :path => '', :except => [:index] do
resources :pages, :path => '' do
end
end
When I run rails routes command I am getting something look like:
site_pages GET /:site_id(.:format) pages#index
site GET /:id(.:format) sites#show
View
<%= link_to 'GO', site_path(site) %>
This code should go to the site#show but it goes to pages#index and it gives me this error message below:
NoMethodError in PagesController#index
undefined method `site_id' for nil:NilClass
Parameters:
{"site_id"=>"site A"}
I have tried:
<%= link_to '', site_path(site), :controller => "sites", :action => "show"%>
<%= link_to '', site_path(id: site.id)%>
but it doesn't work. Any help will be very appreciate

In addition to #jvillian's comment, your routes aren't functional.
Imagine an user wants to see the site with id 1. She could type in the URL my_domain.com/1. Now, she wants to check that site's pages, so she types in my_domain.com/1. How can Rails know what is she referring to?

Since pages is nested inside of sites, you'll (usually) need to have a site to have pages. To accomplish this in your scenario, remove the :path => '' from the pages resource. This will give you routes that look like this:
site_pages GET /:site_id/pages(.:format) pages#index
site GET /:id(.:format) sites#show
Then, you'll need to have a site id anytime you want to access/create its pages. Keep in mind, though, that if you pass a route like mydomain.com/anything_here, you're going to get directed to the sites#show action.

Related

Rails model_path routing error, no route matching "model.2"; should be "model/2"

There seems to be something wrong with my routing paths. Normally I should be able to do something like <%= link_to Profile, user_path(#user||current_user) %> and I move on with my day. For whatever reason I'm failing to understand my user_path is not returning /user/:id like I would expect it to do. Instead it is returning /user.:id
To test this, I loaded a partial with the following code.
app/view/users/_test.html.rb
<%= #user %><br>
<%= #user.id %><br>
<%= link_to user_path(#user), user_path(#user) %><br>
<%= new_user_path %><br>
<%= edit_user_path(#user) %><br>
<%= url_for(#user) %>
This returned
localhost:3000/test
#<User:0x007fb6cd341f08>
1
/user.1
/users/new
/users/1/edit
/user.1
I can't figure out what is causing this to happen. The edit_user_path(#user) works perfectly, but the show doesn't. I have read the Rails Routing Guide from top to bottom about three times and I can't figure it out. The closest I found to my problem was on an old Rails 3.1 gem problem with Devise, but I'm not even using the Devise gem (maybe I should be?).
Why is my route failing? I'm not really looking for a workaround (though I suppose I'd rather have a workaround than no solution), I want to understand why this is happening and fix it. What's going on?
My routes are pretty vanilla, nothing special going on there, but just in case the problem is there and I missed it, here it is.
config/routes.rb
Rails.application.routes.draw do
root 'static#home'
%w( 404 406 422 500 503 ).each do |code|
get code, :to => "errors#show", :code => code
end
#USER PAGES
get '/test' => 'users#test'
get '/signup' => 'users#new'
post '/user' => 'users#create'
get '/user/list' => 'users#index'
post '/user/' => 'users#update'
get '/user/:id' => 'users#show'
get 'profile', to: 'users#show'
resources :users
end
I'd suggest updating your routes as follows:
config/routes.rb
Rails.application.routes.draw do
root 'static#home'
%w( 404 406 422 500 503 ).each do |code|
get code, :to => "errors#show", :code => code
end
#USER PAGES
get '/test' => 'users#test'
get 'profile', to: 'users#show', as: :user_profile
resources :users
end
...as resources :users creates all of the routes I've removed.
The duplicates may have been overwriting a default path, causing the behaviour you're seeing - if you pass an object to a url helper that doesn't expect a parameter, you see the behaviour you're getting (i.e. doesnt_have_an_id_path(#object) => /doesnt_have_an_id.1).
I've also added a name to the user profile path to avoid this clashing. See if this works (perhaps one step at a time to get the cause and effect) - otherwise, try temporarily removing the profile route.
Re that path, you may have a problem in that the users#show action will expect an :id parameter, yet that route doesn't allow for one. This might be causing the current problem, though if not, may cause issues down the line.
Hope that fixes it - shout if you've any questions / feedback when you've tried it out.
In your case the two conflicting routes are:
post '/user/' => 'users#update'
get '/user/:id' => 'users#show'
You are trying to use user_path helper method, thus you need to have user named route.
If you run rake routes for these two routes you will see this:
Prefix Verb URI Pattern Controller#Action
user POST /user(.:format) users#create
GET /user/:id(.:format) users#show
The Prefix column shows you the named routes which are defined for your application. In this case Rails auto-generated named route user for POST /user endpoint. That means user_path will return /user instead of /user/:id as you expected. Rails generate routes like these when it sees a route definition without parameters. For example if you have get /user/some/more in your routes, Rails will auto-generate named route user_some_more for you and they you will be able to use user_some_more_path helper.
In order to fix your particular case you can stop rails from generating route for POST endpoint by doing this: post '/user/', as: nil and give GET endpoint a name you want: get '/user/:id', as: 'user'. Then you will be able to use user_path(user) to generate paths of format /user/:id.

Named routes inserting a . instead of a /

I've been having trouble with named routes in rails 4 (Named route for non resource nesting).
I've moved onto something else, but still struggling with the same problem of named routes for non resource urls.
This is my route from rake routes:
GET /messages/:id/report/:reply_token(.:format) messages#report
messages POST /messages(.:format) messages#create
and my routes.rb
resources :messages, only: [:create] do
member do
get 'report/:reply_token', :action => 'report'#, :as => :message
end
end
Because of the problem I had in my post linked at the top, I'm trying to get a url to the /messages/:id/report/:reply_token route by doing the following:
"#{messages_url(#message, :host => "localhost:3000")}/report/#{#message.reply_token}"
But it's giving me this:
http://localhost:3000/messages.110/report/6bBw22TdaRYcQ3iVzW1ZwA
Why is there a . between the 'messages' and the '110' (message_id)?
Instead of #message, I've also tried #message.id in the messages_url(). I've also tried this: report_message_path(message_id: #message.id, reply_token: #message.reply_token) but got the same error as in my question linked above. I've also tried message_url() instead but it gives undefined method 'message_url'.
You are mixing up routes. messages_url is to generate a URL for create action which does not have ID in its route. Rails assumes 110 is the format and uses the second route (which is named as messages)
messages POST /messages(.:format)
As a solution, name your route like this and also add show action
resources :messages, only: [:create,:show] do
member do
get 'report/:reply_token', :action => 'report' , :as => :custom_message
end
end
And,
custom_message_url(#message, :host => "localhost:3000")
More about naming routes here.
Answerd here already - Rails _path helper generating path with format not id

How to show a profile with link_to rails

In the last we generated a useful link for our mail.
generate an real url with rails for an e-mail
This works fine, very fine. But we want to call the shoe-action :-)
<%=link_to('Link', :controller => 'mycontroller', :action => 'show', :id => #mycontroller.id )%>
The url looks so
http://localhost:3000/mycontroller/show/10
we need this structure
http://localhost:3000/mycontroller/10
The rake routes command said this
mycontroller GET /mycontroller/:id(.:format) mycontroller#show
How do we get the needed structure? Do we need to edit our routes, or is there another way to get the right url?
Try to use the route helper
mycontroller_url(#mycontroller.id)
instead the {:controller => ..., :action => ...}
your link_to helper should look like this for better example i use the user show action
rake routes return this
user GET /users/:id(.:format) users#show
and now I know I can use the user_url(#user) helper
<%=link_to('Link', user_url(#user) )%>

how do I link to a page elsewhere in the app from a Devise page?

My app uses Devise for sign in. I installed it according to the wiki and got it working fine. I recently added a "terms of service" page to my app at "http://127.0.0.1:3000/tos", it routes via a static controller:
match ':action' => 'static#:action'
I've put a link to it in the bottom of my application.html.erb file. I want a link to Terms of Service and Privacy Policy to be at the bottom of each page. But when I go to the users/sign_in page it won't show the link to the TOS page -- instead there's an error (below).
I've removed all the routes in my app except for these (for the purpose of tracking down this issue):
root :to => 'home#index'
#devise routes
devise_for :users, :admins
#static
match ':action' => 'static#:action'
The link is specified like so: <%= link_to "Terms of Service", :controller => "static", :action => "tos" %>
The error is:
No route matches {:controller=>"devise/static", :action=>"tos"}
So Devise is sorta getting in the way of my routing to this static
page. How do I specify the route to go to the root of the app instead
of starting with Devise?
Update: in the short term, the answer was to hardcode it:
<%= link_to "Terms of Service", "/tos" %> -- not an ideal answer though.
In addition to generating the views
rails generate devise:views
you need to configure devise to use the scoped views instead of the views from the gem
config.scoped_views = "true”
in the config/initializers/devise.rb file
This should work then:
match ':action' => 'static#:action', :as => :static
and your link should be generated with something like:
<%= link_to "Terms of Service", static_path(:action => 'tos') %>
I've gotten this error many times. I fix it by adding the route to the devise routing block
like this( in your case )
Update added different routes to try
devise_for :users, admins do
match '/:action' => 'static#:action'
end
match '/:action' => 'static#:action'
devise_for :users, admins do
match '/tos' => 'static#tos'
end
match ':action' => 'static#:action'
I also leave the route outside the block. Not very DRY, but it works.

rails redirect_to problem

I am developing a rails app and have a question.
In my routes.rb:
map.connect 'admin', :controller => "/admin/users", :action => "index"
So when I go to "http://mydomain.com/admin", it redirects to "http://mydomain.com/admin/users/index".
However, the address remains as "http://mydomain.com/admin".
Thus, links in the page are wrong because they are created based on "http://mydomain.com/admin".
What's the solution to this problem?
Sam
try this:
map.connect 'admin/:action/:id', :controller => 'admin/users'
Your code is not redirecting the browser it's just setting up /admin and /admin/users to trigger the same action.
You could try:
map.connect 'admin', :controller => "/admin/users", :action => "redirect_to_index"
Then in your controller write:
def redirect_to_index
redirect_to :action => :index
end
This will send a redirect to the browser, causing it to display the correct URL.
Hopefully there is a better method that only involves routes.rb. This site might be helpful -> redirect-routing-plugin-for-rails
Make sure any same-domain links on the page start with a /, and use the full path. Generally you should use Rails route methods to generate your links when possible. Same goes for using the image_tag and stylesheet_link_tag helpers.
So if you have a link to "privacy.html", change it to "/privacy.html" and you should be all good no matter where in the route structure you are. This is extra nice when you start extracting your view code out to re-usable partials.
Use link_to and button_to (in UrlHelper)

Resources