How to restrict the wild card route - ruby-on-rails

get '/:company' => 'organizations#show', as: 'company_home'
I have this route, this is a way so that different companies registered to my application will login. As I have overridden all the devise related things. This is working fine until I have realized that for every route, this is getting applied
When I hit
get 'employee_dashboard' => 'dashboard#show'
The Parameters: {"company"=>"employee_dashboard"} are going to organizations#show
But I want it to hit dashboard#show how to get around with this?

Move the wildcard route after
get 'employee_dashboard' => 'dashboard#show'
or at the end of route file
get '/:company' => 'organizations#show', as: 'company_home'
so this route will be used only if no other route matches

Related

rails link_to using get instead of post

I'm making a website for a class and I'm trying to implement a friend request function with a model called 'Users' and a join model called 'Relationships'. I have a button on the user#show page that should add a friend by using the create method in the Relationships controller. Here is the code for the button:
<%= link_to "Add as Friend", relationships_path(:friend_id => #user), method: :post %>
When I press the link, however, it tries to access the index method instead. After looking in the console, it looks like the link is sending a GET request, which routes to the index method, instead of a POST request, which routes to the create method. Can someone explain why this error is occurring and how I can fix it?
Edit: As requested, here is what I have in my routes:
Rails.application.routes.draw do
resources :interests
get 'interests/create'
get 'interests/destroy'
get 'home/index'
get 'sessions/create'
get 'sessions/destroy'
resources :users
resources :relationships
resources :subscriptions
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
root 'home#index'
get "/auth/:provider/callback" => "sessions#create"
get "/signout" => "sessions#destroy", :as => :signout
Using a link_to helper indicates to Rails that you'd like to produce an a tag in your HTML. No element of the HTML specification regarding a tags allows for producing POST requests. Because Rails understands the utility of allowing for POST and DELETE requests to be issued using links, however, it provides those options in the link_to helper. It's implementation, though, must use JavaScript under the hood in order to appropriately function.
Check that jquery-ujs is installed, and that your asset pipeline is working correctly in order to use the helper in this way.
You may also evaluate whether using a form_for and a button is better, since that will automatically POST.
I'm pretty sure you are matching the wrong route. Run rake routes and see the route that links to the Relationships#create.
Using 'url' instead of 'path' with the route helper solved the problem for me. So instead of 'relationships_path' use 'relationships_url'.

How does redirect work in rails?

I don't have a /charge page. But I do have a subscription/charge page. I was wondering, how do I say, "if a user goes to /charge, redirect them to subscription/charge" using routes
No route matches [POST] "/charged"
You can modify your routes.rb file to point a url to a specific action
get '/charge', to: 'subscription#charge'
I'm using something similar to below in my application for post:
match '/charge' => 'subscription#charge', :via => [:post], :as => :subscription_charge
you can also write:
root 'subscription#charge'
and you'll be redirected to the charge page if accessing http://localhost:3000

Understanding what's going on with : and # in ruby, rails routes

In the answer to this question about routes in Devise: Devise & Custom Rails User URLs
There is a line of code:
match '/:user' => "users#show", :as => :user_profile
That apparently works for the question asker, but not for me. I end up with
NoMethodError in UsersController#show
undefined method `books' for nil:NilClass
when I go to localhost:3000/username instead of localhost:3000/user/username. I assume because the match line above isn't working correctly and that url does not refer to any user, according to my routes file.
The second url routes me to the user's show page, but I don't want the extra /user in the url.
So I'm trying to figure out exactly what '/:user', :as, and :user_profile mean because I think I'm supposed to substitute a few things here specific to my app. I think :as is some kind of aliased method. I can't find anything in the Devise documentation about a route called user_profile. And I don't know what '/:user' is referring to. An instance of the User object? A user attribute/unique column in my database that I use to refer to specific users? (I use permalink for my user-defined urls).
The route is working for you. Thats why ur getting error from users_controller#show.
In your show action you must be doing something like User.where(:id => params[:id]). But in this case, the attribute in your params is called :user . So to make make both routes work, without any change in the show action, change the route to
match '/:id' => "users#show", :as => :user_profile
Devise documentation won't refer to a 'user_profile' because it is a custom route being used to help address the issue that the questioner (in the linked question) was asking.
match '/:user' => "users#show" means "match any route with a single parameter after / that doesn't match a previously defined route, pair this route to the UsersController 'show' action (passing along the singe parameter as 'user')"
Modifying a route using :as => :anything will provide several helper methods to refer to this route that may be used in controllers, views, and mailers (in this case anything_path and anything_url).
As far as why this won't work for you, this is likely do to a problem with this entry in regard to the rest of your routes or because of your controller action itself. Posting these can help someone track down the exact reason...

A very basic issue with routes in ruby

I am new to ruby and while creating a sample application found out an issue that whenever I go to http://127.0.0.1:3000/people/index by default show action is executed and index is taken as a parameter. This is server log:
Started GET "/people/index" for
127.0.0.1 at 2010-12-23 18:43:01 +0500 Processing by PeopleController#show as
HTML Parameters: {"id"=>"index"}
I have this in my route file:
root :to => "people#index"
resources :people
match ':controller(/:action(/:id(.:format)))'
What is going on here and how can I fix the issue?
The route
resources :people
creates "sub"-routes
get '/people' => 'people#index'
get '/people/new' => 'people#new'
post '/people' => 'people#create'
get '/people/:id' => 'people#show'
get '/people/:id/edit' => 'people#edit'
put '/people/:id' => 'people#update'
delete '/people/:id' => 'people#destroy'
Actually, all of these sub-routes include (.:format) at the end of the recognized path.
The path /people/index would be recognized by the route /people/:id, mapping to the action #show.
The path /people would be recognized by the route /people, mapping to the action #index.
Use the URL helpers people_path and people_url for the /people route.
To get Rails to travel backward in time to before it espoused REST and to understand /people/index, do this:
resources :people do
get :index => 'people#index'
end
You might want to watch this Railscast episode.
A couple things to keep in mind when working with your routes:
rake routes dumps the map of URLs to your controllers
When providing backwards compatibility, redirect the user to the correct path
I personally have yet to upgrade my app to Rails 3, and I'll be dragging my feet until I really need to do it (just got it out the door not too long ago). In Rails 2.x you had resource routes, but if you kept the default controller/action/id route it would fall through and resolve. It appears that is no longer the case in Rails 3. Essentially your resource routes handle all URLs in that resource namespace (/people in your case).
To provide backwards compatibility, I would add a redirect route to resolve that incompatibility.
match "/people/index", :to => redirect("/people")
The main reason for that is to prevent users from saving an incorrect URL for their personal links--while allowing legacy users to still be able to get where they meant to go.
Edit: New answer, removed pointing out the typo in the question.

Ruby on Rails 3: Change default controller and parameter order in routing

I have a Rails app that has a controller called domain which has a nested controller called subdomain and stats. I have defined them in routes.rb:
resources :domains do
resources :subdomains, :stats
end
I have changed the to_param of the domain and subdomain models to use the name of the domain, e.g.: the routing I get is http://site/domains/foo/subdomains/bar.
I would like to tidy it up to so that instead of using http://site/domains/foo/subdomains/bar I could access it with just http://site/foo/subdomains/bar. I have tried the following in routes.rb:
match "/:id/" => "domains#show", :as => :domain
Which works fine, but it only gives me the ability to use the path http://site/foo but for example http://site/foo/subdomains/bar doesn't. I could create match lines for every respective model and nested model but that does nothing to other helpers besides domain_url - i.e. edit_domain_url points to /domains/foo/edit/ instead of /foo/edit.
Is there a way to change the routing so that the resources generates helpers that point to the root url without the 'domains' part?
The single match in your routes creates only one route. Resource helpers create many routes at once. Luckily there are a lot of options for customisation. If you want to omit /domains/ from your paths, it's as simple as:
resources :domains, :path => "/" do
resources :subdomains, :stats
end
With the above in config/routes.rb, running rake routes says the following:
domain_subdomains GET /:domain_id/subdomains(.:format)
domain_subdomains POST /:domain_id/subdomains(.:format)
new_domain_subdomain GET /:domain_id/subdomains/new(.:format)
edit_domain_subdomain GET /:domain_id/subdomains/:id/edit(.:format)
domain_subdomain GET /:domain_id/subdomains/:id(.:format)
domain_subdomain PUT /:domain_id/subdomains/:id(.:format)
domain_subdomain DELETE /:domain_id/subdomains/:id(.:format)
domain_stats GET /:domain_id/stats(.:format)
domain_stats POST /:domain_id/stats(.:format)
new_domain_stat GET /:domain_id/stats/new(.:format)
edit_domain_stat GET /:domain_id/stats/:id/edit(.:format)
domain_stat GET /:domain_id/stats/:id(.:format)
domain_stat PUT /:domain_id/stats/:id(.:format)
domain_stat DELETE /:domain_id/stats/:id(.:format)
domains GET /(.:format)
domains POST /(.:format)
new_domain GET /new(.:format)
edit_domain GET /:id/edit(.:format)
domain GET /:id(.:format)
domain PUT /:id(.:format)
domain DELETE /:id(.:format)
Looks like all the routes you need!

Resources