Why is custom action for resource not working? - ruby-on-rails

I have an AppleController
it has a def sliceme method
when I go to: /apple#sliceme
it routes to #index
In my routes.config I have
resources :apples
Why?? And what is the correct route??

Resources will create the CRUD method routes (see here)
If you want to specificity another route you can specify it like so in your routes file:
get "apple/sliceme", to: "apple#sliceme"
Or
resources :apple do
get :sliceme, on: :collection
end
To check what routes actually exist, run rake routes in the terminal

Related

Rails 5: How to overwrite route parameters for extra member route

In Rails 5 I've figured out how to
Overwrite the route parameter from id to something like name
Add another route for a resource
So that my routes.rb looks something like this
Rails.application.routes.draw do
resources :cats, param: :name
resources :cats do
get :preview, on: :member
end
end
I've noticed however that my additional preview route does not keep the overwritten named route parameter. Instead, when looking at the output from rake routes, I have something that looks like this.
GET /cats/:id/preview(.:format)
when what I was expecting, and trying to achieve, was a route that looks like
GET /cats/:name/preview(.:format)
How do I both add an additional route to a resource while overwriting the parameter?
You're duplicating your routes entries for cats, and you've provided the block for declaring the preview route on the entry missing the param name override. You need to provide the override and the block in the same route declaration.
Rails.application.routes.draw do
resources :cats, param: :name do
get :preview, on: :member
end
end
This gives you the route you want:
$ rake routes
Prefix Verb URI Pattern Controller#Action
preview_cat GET /cats/:name/preview(.:format) cats#preview

Rails how to make example.com/post/1 to example.com/blog/post/1

I have a blog with root
root 'posts#index'
And works best with example.com/ to example.com/posts
But what I want is something like this:
example.com/blog/posts/1.
I've tried creating blog Controller and add
resources :blog do
resources :posts
end
But this is making my routes to blog/:id/posts/:id
If you don't have the relationship between the post and the blog as you mentioned, rails gives you the freedom to declare routes as our own.
so, to make the route example.com/posts/1 to, example.com/blog/posts/1, just add a custom route at the last.
get '/blog/posts/:id', to: :show, controller: 'posts'
what this does is over rides the previous route and make this route final.
Now type rake routes and it will give the last route for you as,
GET /blog/posts/:id(.:format) posts#show
Now you can access using,
example.com/blog/posts/1
Reference for rails routing
Just to expand upon #Sravan answer. If you have multiple routes that will start with /blog/ you might want to check Rails guide on routing.
You can add something along the lines of
scope '/blog' do
resources :posts
resources :users
resources :images
end
Which will create corresponding routes under /blog/.
namespace :blog do
resources :posts
resources :users
resources :images
end
And your controller with namespace will look like this: Blog::PostsController

Missing helper path when doing rake routes

I wanted to do like http://domain:3000/users/id/edit/details. I've already create a new action under app>views>users>details.html.erb. Also in UsersController i put:
def details
....
end
when I run rake routes, I got missing Helper Path/Url on the left side for GET, /users/:id/edit/details(.:format), Users#Details.
Also in routes.rb, I've:
resources :users
I try to insert:
match "users/:id/edit/details", to: 'users#details', via: 'get'
but stil didnt solve my problem. Please help me!
In routes, you'd want to do this:
resources :users do
get :details
end
In this, you'd have the advance form. The url for this will be
/users/:id/details/
Check rake routes to see what's in there.
You may need another update method (the form post action) to handle the advanced form
What you are looking for is called nested resources
resources :users do
resources :details
end
Take a look at http://guides.rubyonrails.org/routing.html#nested-resources for more info

How can I guess the route helpers that are created with match in Rails?

I have created a route in the routes.rb file like this:
match ':controller/:action/:id'
I tried invoking add_posts_path() and add_post_path() from my view and in both cases I got similar error messages like this one:
undefined method `add_post_path' for ...
I have tried declaring my match route both before and after the resources :posts declaration.
Are any route helpers created for such a route? I am unsure what helper methods can be used with such a match rule.
You can name routes with :as parameter
match '/foo/bar', to: 'foo#bar', as: 'foo_bar'
and then use foo_bar_path in your view
http://guides.rubyonrails.org/routing.html#naming-routes
If you have resources :posts, you have a helper new_post_path to add new posts. Run rake routes to see your apps routes.
add_post_path does't follow Rails routes convention for resources and if you need it, must add a custom method:
resources :posts do
get :add, :on => :collection
end
You can read more about this in this Rails guide.
When you define match ':controller/:action/:id', you set the format of your app's urls and their params, but this do not magically will define routes helpers.

Custom actions in rails controller with restful actions?

I'm having some trouble with using creating my own actions inside a controller I generated using the scaffold.
I understand everything maps to the restful actions but I'm building a user controller where users can login/logout, etc but when I created the action and declared it in the routes.rb I get this error when I visit users/login
Couldn't find User with id=login
It tries to use login as a ID parameter instead of using it as an action.
Routes.rb
match 'users/login' => 'users#login'
I think I'm doing something wrong with the routes so if anybody could help me that would be great.
Thanks
I assume your routes.rb looks like this:
resources :users
match 'users/login' => 'users#login'
The problem is that Rails uses the first route that matches. From the documentation:
Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action’s route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.
So either define your custom route before resources :users:
match 'users/login' => 'users#login'
resources :users
…or use this syntax for adding more RESTful actions:
resources :users do
collection do
match 'login'
end
end
To see the existing routes (and their order) run rake routes from the command line.

Resources