Controller doesn't equal to model name in Rails - ruby-on-rails

I've model called BlogPost and controller called BlogPostsController that has all basic CRUD methods for BlogPost.
I'm trying to understand how I can route users to have URL like /blog/post-name instead of /blog_posts/post-name and "disable" in general URL /blog_posts. Should I rename my controller or should I change routes (and how)?

Update your routes and add the :as option to your blog post resource route
map.resources :blog_posts, :as => 'blogs'

Related

Route to /post/new instead of /posts/new in rails?

This is related to a question I asked here: undefined method `posts_path' for #<#<Class:0x007fe3547d97d8>:0x007fe3546d58f0>
I was told to switch my controllers, view etc from "post" to "posts" which fixed the issue, however if I did want to use the URL /post/new, how would I do that without receiving the "undefined method `posts_path'" error I was before?
I don't understand why it's looking for "posts_path" when my controller, model and view are all called "post".
Add this before resources :posts line/block in routes.rb file,
get '/post/new', to: 'posts#new'
When you define routes using resources :posts, by default the route to the new action is /posts/new, So to override the same you need to define custom route like I did above. Also, to search the routes, Rails scans the routes.rb file from top to bottom, whatever matches first is taken. Therefore, to override the default behaviour, I asked you to define this custom route before the default routes.
Hope that helps!
I would suggest that you take a look at Rails Routing Guide.
In short:
Because the model Post describes only one record, it makes sence to call the model Post and not Posts.
With resources :posts within your routes.rb you define that you will have multiple Post objects and you want to expose all CRUD actions with a restfull interface through your controller. Your controller is named PostsController that too makes sence, because your controller provides CRUD actions for all Post objects not only one.
Furthor more rails generate some helpers for every defined route:
posts_(path|url) returns /posts=> shows multiple posts => plural helper name
new_post_(path|url) returns /posts/new => show one post for edit => singular helper name
edit_post_(path|url)(:id) returns /posts/:id/edit => edit one post => singular helper name
photo_(path|url)(:id) => show one post => singular helper name
The route name is always plural because you are always changing the resources. For instance add a new post to the posts resources.
You can also define a singleton resource via resource :geocoder in this case you say you only have one of this thing. For singletons helpers and routes are slightly different. But I saw it until now only rarely.

How to add multiple new/create routes in Rails 3

I have a client controller and views which already functions for all the default actions. How do I add a new_account and create_account actions that also work with routing?
The idea is... there are new clients, but some clients can also function as an account that logs into the website. I want to prompt for different fields based on whether a client is being created or a login account is being created. I don't want two separate models with duplicate information.
client_controller.rb - index, new, create, edit, update, destroy, new_account, create_account
client views - I have views for each of the actions within the controller.
Routing - ../new_account should display the new_account view for the client model, not the new view.
Hopefully this makes sense. I'm guessing this isn't difficult but I'm just missing how.
Try:
match 'new_account', 'client#new_account', :via => :get
match 'create_account', 'client#create_account', :via => :post
View all your routes by running rake routes.
Refer to more info on routing here: http://guides.rubyonrails.org/routing.html
Put this in your routes.rb
resources :clients do
new do
scope type: 'account' do
get :account, to: 'clients#new'
post :account, to: 'clients#create'
end
end
end
and the actions you need will be accessible at GET|POST /clients/new/account.
In the controller you'll have params[:type] to indicate this specific case.

rails controller action routing

I'm looking to "automatically" generate routes based on actions defined in a controller. resources routing (as far as I know) only automatically generates routes & helpers for http verbs. In this instance I'm serving mostly static pages using rails and have no need for http verbs in my controller.
Specifically:
In a controller I have defined actions which refer to those mostly static pages.
def action
end
In the routes file I have a bunch of
match "/url" => 'controller#action'
I'd like all those matched routes to be generated automatically based on the actions in the controller. Something CONCEPTUALLY along the lines of:
for actions in controller.erb do |action|
'match "/action" => "controller#action"
end
Is this possible? Would I write the code in the routes file directly?
I also have some nested actions to consider... a controller action may be:
def action
def nested_action
end
end
I'd appreciate any thoughts on this matter. Thanks.
What's wrong with the normal /:controller/:action idea?
That won't deal with nested actions, but... I'm having a difficult time understanding why you'd ever want that.
You can do something like this:
controller :controller_name do
get "path/action" => :method_name, :as => :path_action
post "path/save" => :method_name, :as => :path_save
end
That is, you can group different routes within a controller using the method above.

Different controller actions for POST and GET requests at the same route in Rails

I want to route the same address, e.g., 'http://server/path' to different controller actions depending on the request type, whether it is a GET or POST request.
How can I do that in Rails?
Thanks!
get "/path" => "controller#get_action"
post "/path" => "controller#post_action"
I think you could do this:
match '/path' => 'controller#action', :via => :get
match '/path' => 'controller#another_action', :via => :post
Generate a resource using the Rails scaffold and you'll see how it should be done:
./script/generate scaffold Person name:string
EDIT
Got downvoted so maybe I should expand my answer. The scaffold demonstrates how to build a RESTful resource. By convention, a POST will map to the create method in the controller, a GET will map to the index method (or the show method if an ID is present), etc. All you need add to your routes.rb is:
resources :people

Help with rails routes

I seriously cant understand why this is so hard... I have some experience with other mvc frameworks but always heard rails was the easiest to code in.... right now I cant even get to my controller methods if i want to.
I used scaffold to creat 'student' which automatically created for me the controller, model and views for basic CRUD.. but now I just want to add a method "helloworld" to my controller and when i go to
http://localhost:3000/students/helloworld
I get a
Couldn't find Student with ID=helloworld
error.
what am I missing?.. I know its got to do with routes and the REST thing but I still cant figure out then how else am I supposed to use my own methods... do I have to edit my routes.rb file everytime I create a new method?.. please help
Routes for models in Rails are divided into 2 groups. Ones that act on a single objects (think edit, update, delete) and ones that don't have a single object to act on (new, index). If you want to create your own method that doesn't take an object ID you need to add a route config for that method in your routes file. The methods are either member or collection methods. Member methods URLs look like /model/id/method_name. Collection methods look like what you want (/model/method_name). Here is an example for your students model (routes.rb)
map.resources :students, :member => {:some_member_function_example => :get },
:collection => { :helloworld => :get }
Note: You can just remove the :member => ... from the config and only have collection if you have no member methods to define.
Link /students/foo will not call the foo method of the students_controller. That's because REST mappings in Rails includes /:controller/:id route for GET. And your link matches this pattern.
In order to override that path (for methods with no parameters, like yours) use the following snippet:
map.resources :students, :collection => {:method_name => :get}

Resources