To access a dashboard this is the url: http://localhost:3000/dashboards/1
I want to hide idand show nothing in the url to do this: http://localhost:3000/dashboards/
I see another questions but all of it show to substitute id for name for example.
How can I just hide the id?
You just need to define a new route in routes.rb. If you're using resources :dashboards then that path is already defined and conventionally reserved as an index to list all available objects. Something like this should work:
get 'dashboards' => 'dashboards#show'
Note also that if you need the id in the controller you can no longer rely on params to grab the id as it's no longer in the url and available. You will have to use sessions instead.
Map the controller as a resource instead of resources. In your routes.rb file change
resources :dashboards
to
resource :dashboard
This assumes your controller is called DashboardsController. If not, pass the appropriate controller name.
resource :dashboard, controller: 'whatever_controller'
You may also want to restrict to the show action only, unless you have other actions.
resource :dashboard, only: [:show]
This will create the route
GET /dashboard
If you don't limit the actions, you'll get also
GET /dashboard/new
POST /dashboard
PATCH /dashboard
DELETE /dashboard
Related
I am looking to set the show action for a controller to a specific path (a path without the controller prefix). I know this can be done by controller by doing this
resources :items, path: ''
But is there a way to do this on only one specific action within the controller?
My end goal is to be able to say www.example.com/my-item-name and take the user to the item without changing the URL. I tried using a catchall route but redirecting adds the prefix back which I do not want.
Any ideas?
You can specify which controller and action respond to a certain route in your routes.rb file, like this:
get 'something', to: 'controller_name#action_name'
See Rails Routing Guide.
You can define single routes manually with the match, get,post, put, macros:
get :bar, to: 'foos#bar'
get :bar, controller: 'foos' # works the same as above
post :bar, to: 'foos#bar'
You can also use scope if you want to route multiple routes to the same controller more elegantly:
scope controller: 'foos' do
get :bar
get :baz
end
The guide Rails Routing from the Outside In has a section named Adding Routes for Additional New Actions in chapter 2, Resource Routing: the Rails Default, with this example:
resources :comments do
get 'preview', on: :new
end
which generates the following route:
Prefix Verb URI Pattern Controller#Action
preview_new_comment GET /comments/new/preview(.:format) comments#preview
The same result can be achieved at least in two other ways:
1) Adding a collection route inside resources :comments like get 'new/preview', to: :preview, on: :collection (if you don't bother about the route name)
2) Adding just this route to the corresponding singular resource:
resource :comment, only: :preview do
get 'new/preview', to: :preview, as: 'preview_new', on: :collection
end
which has exactly the same behavior.
So why there is a on: :new option? Is it just a shortcut? If it is, why it's just for 'new actions' and there are not any similar options for the other default REST actions, like on: :edit or on: :delete?
This is a shortcut that is unique to the RESTful action new, in which an object is instantiated but not yet persisted.
For example, if you are filling out a form for a new object, you would provide yourself with a link_to "preview", which sends all of the attributes to your preview action (instead of directly to create). This is similar to a show view, but for an object that only exists in memory.
This functionality isn't logical for destroy, update, index, show or create. I suppose you could use a preview on an edit action after assigning new attributes before sending to update, but you'd have to create the route manually.
Actually there is a subtle difference.
If you add it to the resources :comments the path helper generated has a pluralized resource name so it will be preview_new_comments and the path will be /comments/new/preview. If you add it to the corresponding singular resource it doesn't pluralize the resource name in the path so you get /comment/new/preview but the helper will be preview_new_comment. Using :on will generate the path helper with the singular resource preview_new_comment but the route will have the pluralized resource /comments/new/preview.
To get the same behaviour you could use the following more verbose route outside the resource
get 'collections/new/preview', to: 'collections#preview', as: :preview_new_comment, on: :collection
I'm not sure why there is no on: :<action other than new> option. They advise against having too many new actions in the documentation but if you are going to have a new 'new' it seems a reasonable possibility you might need an new 'edit' to edit your new 'new'. However, things become more complicated because to edit you would need a path like collections/<id>/edit/preview and the path helper of the solution above stops working as you might expect. More importantly at this stage maybe you start veering away from the original intention of the option.
I want to implement a search function in the controller, which contains "show, new, create, etc..."
I added in route.rb:
get 'apps/search' => 'apps#search'
and in apps_controller.rb:
def show
#app_info = App.find(params[:id])
end
def search
# get parameter and do search function
end
but each time when i request the /apps/search?xxx=xxx then it will be rendered by show... and then search?xxx=xxx is the parameter for method show...
should I rather create a new controller for search? Or is it possible to implement search as my requirements?
Your routes are incorrectly prioritized - somewhere else in your routes file (before the get 'apps/search' line) you have resources :apps, which defines a route that matches the same regex as apps/search.
Routes match from top to bottom, so if you check the output of rake routes, you'll see that your request to apps/search is actually matching apps/:id - which is the show route of your apps resource.
Either move the apps/search route above the resources :apps declaration, or alternatively declare your search route as part of the apps resource, eg.
resources :apps do
get :search, on: :collection
end
(this will define apps/search in the way you want).
For more information on routing: http://guides.rubyonrails.org/routing.html
I think you should edit route.rb as the following:
get 'apps/search' => 'apps#show'
The Rails' way to "say" search is a new route to the apps controller is using collection. So, for example, supposing you already have a resources :apps, you can do:
resources :apps do
get 'search', on: :collection #or you can use another HTTP verb instead of get
end
And that would give you:
search_apps GET /apps/search(.:format) apps#search
This is my first Rails project, I am trying to piece things together slowly.
When I'm trying to view the page I generated using rails g controller <controller> <page>, I find myself going to 0.0.0.0:3000/controller/page.html, How can I configure it so that my route file globally allows viewing the page via the page name, rather than controller/page, if no such way exists, then how can I route controller/page.html to /page.html
I've looked around, and haven't really found any explanation, maybe I'm looking in the wrong places?
In config/routes.rb:
get '/page' => 'controller#action'
If your controller is:
class UsersController < ApplicationController
def something
end
end
Then config/routes.rb would be:
get '/page' => 'users#something'
For static pages you could want to use public folder though, everything you put there is directly accessible, for example public/qqqqqq.html would be accessed in localhost:3000/qqqqqq.html
We've just achieved this by using the path argument in resources method:
#config/routes.rb
resources :controller, path: ""
For you specifically, you'll want to make something like this:
#config/routes.rb
resources :static_pages, path: "", only: [:index]
get :page
get :other_page
end
#app/controllers/your_controller.rb
def page
end
def other_page
end
This will give you routes without the controller name. You'll have to define this at the end of your routes (so other paths come first)
Obviously this will form part of a wider routes file, so if it doesn't work straight up, we can refactor!
It sounds like this is a static page, so you can do as juanpastas says, or another option is to create a folder under your app/views directory to hold these pages. Maybe something like
app/views/static_pages/the_page.html.erb
Then in your config/routes.rb you can add:
match '/your_page_name', to: 'static_pages#the_page', via: :get
Rails 3.1. I have a table places. It has a column called type which has value such as cafe, restaurant, etc. Just one value in each row.
In my routes, I define the resources as:
resources :places
The URL is:
http://domain.com/places/123?type=cafe
I always have the type appended in my URLs because I use that to determine which navigation menu to be highlighted.
Now, I want to create a friendlier URL. How can I create a URL that reads either of these:
1. http://domain.com/places/cafe/123
2. http://domain.com/cafe/123
Many thanks!
There are two types of routes - resourceful and non-resourceful. It sounds like you're trying to do a mix between the two. Unfortunately, resourceful route URLs can't be customized like you're trying to do via resources, but you can add additional routes to match the URLs you're trying to make.
To accomplish this, you'll have to create non-resourceful routes such as these:
resources :places, :only => [:create, :update, :destroy]
match 'places/:type/:id' => 'places#show'
match 'places/:type' => 'places#index'
match 'places/:type/new' => 'places#new'
match 'places/:type/edit' => 'places#edit'
You don't need to create special routes for create, update, and destroy (though you could). The user never really sees those anyway. Just include the place type as a parameter in your forms and delete links, and it will be available in the controller the same way that it would as if it were coming from the URL.
In the controller, access the type via params[:type].
Why don't you use the value stored in #place.type, where #place = Place.find params[:id], to determine which navigation to use?