I am using Ruby on Rails 3. In my project I have many classes and some of those are stated in the routes.rb file like the following:
#routers.rb
resources :users
namespace "users" do
resources :profiles
...
end
With the above code I can access the following URLs:
<my_web_site>/users/1
<my_web_site>/users/1/edit
...
# and also
<my_web_site>/users/profiles/1
<my_web_site>/users/profiles/1/edit
...
What I would like to do is to redirect some URL requests to others URL but if in the routes.rb file I redirect all those, some controller actions will not work properly because also those requests are redirected (GET, POST, ...).
How can I solve this issue?
P.S.: I know that (maybe) my router statements are wrong, but at the moment I am looking for a easy solution too the problem. However suggestions about this matter are welcome.
Ok, looks like you want to set up a redirection that will only apply for to a given path and just one HTTP verb. This seems to be what you are looking for:
#routers.rb
resources :users
match "/users/profile/:id" => redirect("/profiles/%{id}"), :via => :get
namespace "users" do
resources :profiles
...
end
Based on this routes every GETrequest hitting /users/profile/1 will be redirected to /profiles/1 while any POST, PUT or DELETE requests won't be suffering the redirection.
The :via param will execure the redirection only if the request method math the given value. It also accepts an array of verbs so, for example, you can redirect :via => [:post, :put]
If you add more detailed information about the specific redirections that you need we can create a better example.
Check this great article, it will help you:
routing
you can define urls that you need to redirect to in routes.rb.
For example:match 'some_url/:id' => redirect_to('/path_to_redirect')
Related
My site used to have a mobile view here:
https://www.example.com/m/home
We have deprecated the mobile views and now I need a simple way to trim the /m/ off the URL so that the request proceeds to the correct page.
Example:
https://www.example.com/m/about => https://www.example.com/about
https://www.example.com/m/user/:id => https://www.example.com/user/:id
I'm hoping to solve this in the Rails routing without having to introduce a new controller action or meddle with nginx. I have 100+ routes. Thanks in advance.
Rails version: 4.2
There is a redirection module (also documented in the guide).
Something like :
get '/m/about', to: redirect('/about')
get '/m/user/:id', to: redirect('/user/%{id}')
Which you can combine with route globbing for a generic solution :
get '/m/*path', to: redirect('/%{path}')
How about just refactor your routes a bit:
Eg: Previous routes.rb
resources :users
# ...
Now, it becomes:
['m', ''].each do |sc|
scope sc do
resources :users
# ...
end
end
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'.
I know rails uses the controller action style urls like www.myapp.com/home/index for example
I would like to have a url like this on my rails app, www.myapp.com/my_page_here is this possible and if so how would I go about this?
You just use a get outside of any resources or namespace block in your routes.rb file:
get 'my_page_here ', :to => 'home#index'
Assuming you are using Rails 3+, do NOT use match. It can be dangerous, because if a page accepts data from a form, it should take POST requests. match would allow GET requests on an action with side-effects - which is NOT good.
Always use get, put, post or these variants where possible.
To get a path helper, try:
get 'my_page_here ', :to => 'home#index', :as => :my_page
That way, in your views, my_page_path will equal http://{domain}/my_page_here
you just need to make a routing rule to match that url
in this case it will be something like
match 'my_page_here' => 'your_controller#your_action'
your controller and action will specify the behavior of that page
so you could do
match 'my_page_here' => 'home#index'
or
get 'my_page_here', :to => 'home#index'
as suggested in other responses.
for index action in home controller if you have such a controller
see http://guides.rubyonrails.org/routing.html for more details
also see Ruby on Rails Routes - difference between get and match
I've been digging around on subdomains in Rails for a couple days and haven't found a good explanation of this yet...
I have a rails app which has a blog integrated into it, and I'd like to put that blog on a subdomain. Ie. blog.myapp.com.
Now, within the blog I want the user to be able to view posts, blog.myapp.com/posts/123. However, if the user were to click to any other resources on the site, say videos for example, I'd like them to be redirected back to root, ie. www.myapp.com/videos/123. I don't want blog.myapp.com/videos... to cause a routing error, I just want it to redirect.
Basically, I'm looking for the simplest way to setup a subdomain and specify that certain controllers use that subdomain and the others don't. Ideally I'd even like the controller layer to handle redirection both ways, so that in views I could link back and forth to things just using helpers like post_path(123) and video_path(123) and that the subdomain would automatically be used or not used based on which controller was serving the view.
I tried putting all the controllers in a constraints block, ie:
constraints :subdomain => 'www' do
resources :sessions
resources :users
resources :videos
root :to => 'home#show'
end
constraints :subdomain => 'nexturb' do
resources :posts
root :to => "posts#index"
end
root :to => 'home#show'
However this doesn't seem to work well, I've especially had trouble with getting redirection between links to work very consistently.
I'm pretty sure other people must have run into this issue in the past, but I can't seem to find a good example of this situation in writing. What's the best way to handle this?
With help from here, here, and here... I finally figured this out:
constraints :subdomain => 'blog' do
scope '', :subdomain => 'blog' do
resources :posts
end
root :to => 'posts#index'
end
This causes the posts_path helper to correctly send visitors to the subdomain.
I used #Andrew's answer. Some extra tips:
This railscast suggests using lvh.me to make subdomains work on localhost by visiting urls like blog.lvh.me:3000 or lvh.me:3000
Add the routes available in Andrew's answer
You may then have to add this to config/development.rb:
config.hosts += ["lvh.me", "blog.lvh.me"]
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.