Naming convention for rails - ruby-on-rails

So this might be a silly question, but I need to create a new page.
I currently have a controller called jobs, that let's you create a job. However what I want is for there to be a step 2 of the part of creating a job.
Should I create a new controller, and create an index page there, or should I create a page say called part2.html.erb and in the controller create the def part2?
Which leads me into the question is it okay to create names for pages that are not index, show, new, edit and if you need a new page like that create a new controller for it. Or would it be ok to call it things like part2 f.ex. What's the best practice?

It's perfectly fine for you to define controller actions however you like. It's just in your best interest to follow CRUD (create, read, update, delete) 95% of the time.
Personally, I have a fallback in my routes file which sends any "unknown" request to the Pages controller. EG..
# routes.rb
match ':action', :via => :get, :controller => 'pages'
This would work for mysite.com/privacy-policy, mysite.com/contact-us.. whatever
With regards to creating a multi-page form, check this out
http://railscasts.com/episodes/217-multistep-forms

Related

Multiple index actions in Rails

I have a Game model and GamesController. Currently my index page shows first 10 records from the database for the purpose of the application. However, i want to make another page where all of the games are being shown.
My question is, what's the Rails way™ of achieving this purpose? Is it possible to have the index action of my GamesController to make requests based on what URL i want to render? (Something like http:localhost:3000/all)
Rails 3.1 - How do I organize multiple index actions for the same model?
was the closest to my issue, but the question tackles problem from rails 3.1 dating back to 2012.
You can really only have one index action per controller, but there are a couple of ways you can achieve this.
First, simply create a new action and have a separate page. Think of an appropriate name for it and create the controller, route, and view. You can keep the amount of code to a minimum by having much of the view code in a partial and use that in both views.
The other way to do this, if you really only want one action, is to pass a parameter to the index controller and query the database based on that parameter. For instance:
link_to 'link text', game_index_path(:g => 'all')
will create a url like: http://domain.com/game/index?g='all' and in the controller you can do this:
def index
which_games = params[:g] # should be all in this case
#games = Game.where(:criteria => which_games)
end
You can use this same method to implement sorting and filtering and all sorts of things.

How to add a view in rails

I am quite new to rails but i have searched a lot how to do this but it doesnt seem to work for me. Im trying to create a new view called request for my model called steppy_steps, so i created a new file in the views directory called request.html.rb, added this to my routes, match '/request' => 'pages#request', also tried get "steppy_tests/home", and lastly added (def request, end), to my Steppy_Tests_Controller.rb but when i check the url it gives me an error:Couldn't find SteppyTest with id=home
I cant figure out what to do any help would be great! Thanks in advance.
You should read up on the MVC programming pattern (which is what Rails is based on)
In order to make a view, you need to have the controller and model aspects in place too. I think you're doing this already, but to help you understand more, I'll outline below:
Views : Controller Actions
If you want to show a view from the steppy_steps controller, you need to first have a controller action set up to handle the request. You'd normally use a self-named controller for this (controller name steppy_steps), and have various actions for that
In your routes, you'll then "capture" the request to your steppy_steps controller like this:
#config/routes.rb
resources :steppy_steps
This will create a set of RESTful routes, which you can then translate into your controller, like this:
#app/controllers/steppy_steps_controller.rb
def index
#Index code
end
def show
#Show code
end
This will allow you to create a views directory which can contain the views for /views/steppy_steps/show.html.erb and /views/steppy_steps/index.html.erb
Routes Are Super Important
The error you're getting is caused by you sending /home to your view
The problem here is that if you're using a route which has an in-built id param (the show action routes have this), then Rails will look for the extra params after the URL
To fix this, you'll have to provide more of your code, but I also believe you'd be better understanding the fundamentals of Rails a little more
Adding Routes
You can add routes & views as you wish
If you're looking to add a requests route / view, I'd do this:
#config/routes.rb
resources :steppy_steps do
collection do
get :requests
end
end
This will allow you to create /steppy_steps/requests

How should I handle triggering an "action method" through a RESTful Controller?

I am trying to keep my controllers nice a RESTful. One thing I keep running into is the need for a button or link on the site to trigger a specific event on a model. For example:
#user.ban!
Currently, I either make a custom named route on the users controller or if it's a more complex set of related actions, I create a new controller that acts on the same model as another "traditionally named" controller.
What is the best approach in this type of situation? What factors weigh into the decision?
In your routes you would typically have a resources declaration looking something like this
resources :users
The best way to add a restfull route to this is to define a ban method in the users controller and add a member route to the users route so your route ends up looking like this
resources :users do
member do
post :ban, :pay, :whatever
end
end
Use a memeber route for form post put actions, i.e. when using button_to or form_for (plus others) view helpers. Use collections for get requests (i.e. links)
Alternatively you could use <%= button_to 'Ban', #user %> then in the update action for the users controller check the commit params for the text ban and act accordingly
Actually I use this myself occasionally like so
if params[:commit] == 'Ban'
# do something like calling a ban method setting a flash notice or alert and redirecting
else
normal controller flow
end
Better still. Use i18n to display the text on the button and check the same i18n value against the commit param thereby leaving you free to change the text text on the button by updating the i18n yml file without breaking your controller code
First off, what jamesw says is good. There are lots of details here...
http://guides.rubyonrails.org/routing.html#non-resourceful-routes
http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
... and I actually go with that for whatever unconventional routes I need. About the "factors that weigh into this decision," though... I would first ask myself if this eccentric action is absolutely needed, because more often than not Rails' "convention over configuration" policy comes in. From experience, I find that it's pretty rare for me to need atypical actions. I guess if you can justify it, though, don't feel guilty and go with it.
I have rarely ever had to make a whole 'nother controller, though.

One Controller Action or Two for Ruby on Rails pages

I currently have one model, one controller with one action to list all the items in the model.
What I need to do is display different data from the model in two separate views. Is there a way I can use one controller action to display different views based on params, or should I create another action?
The reason why I hesitate to create another action is because I'll have to essentially duplicate all the routing I setup for the previous action.
Thanks for any ideas.
I'm not entirely sure that you've provided enough information to give what could be considered a 'good' answer, but if I'm understanding you correctly, this should be possible.
For example, couldn't you do something like this?
def show
#my_objects = MyObject.all
if params[:full_view]
render :action => 'show_full_fiew' and return
end
# if you get here, it will render the 'show' action
end
Let me know if that helps. If you could give some more information, I might be able to clean up this example to be a bit more informative.
You don't mention if you're using resource routes or not. If so, I'd just add a new option to your routes.
map.resources :products, :collection => { :some_great_name => :get }
You really shouldn't worry about adding views or new actions to your controller. An action should usually only have a few lines of code. If your controller actions start to grow in complexity you should think about moving that logic into your model.

Why do I need to work harder to make my Rails application fit into a RESTful architecture?

I started a Rails project recently and decided to use RESTful controllers. I created controllers for my key entities (such as Country) and added index, new, edit, create, show, update and delete. I added my map.resources :country to my routes file and life was good.
After development progressed a little, I started to encounter problems. I sometimes needed extra actions in my controller. First there was the search action that returned the options for my fancy autocompleting search box. Then came the need to display the countries in two different ways in different places in the application (the data displayed was different too, so it wasn't just two views) - I added the index_full action. Then I wanted to show a country by name in the URL, not by id so I added the show_by_name action.
What do you do when you need actions beyond the standard index, new, edit, create, show, update, delete in a RESTful controller in Rails? Do I need to add (and maintain) manual routes in the routes.rb file (which is a pain), do they go in a different controller, do I become unRESTful or am I missing something fundamental?
I guess I am asking, do I need to work harder and add actions into my routes.rb file for the privilege of being RESTful? If I wasn't using map.resources to add the REST goodies, the standard :controller/:action, :controller/:action/:id routes would handle pretty much everything automatically.
I would treat search as a special case of index. Both actions return a collection of resources. The request parameters should specify things like page, limit, sort order, and search query.
For example:
/resources/index # normal index
/resources/index?query=foo # search for 'foo'
And in resources_controller:
before_filter :do_some_preprocessing_on_parameters
def index
#resources = Resource.find_by_param(#preprocessed_params)
end
As for index_full and search_by_name, you might look at splitting your current controller into two. There's a smell about what you've described.
Having said that, you're absolutely right that there's no point in forcing your app to user restful routes when it doesn't deliver anything over /:controller/:action/:id. To make the decision, look how frequently you're using the restful resource route helpers in forms and links. If you're not using them, I wouldn't bother with it.
If I go beyond the standard CRUD actions with my models, I normally just add the methods as required. Searching is something I add to many controllers, but not every one, so I add it and maintain the routes normally:
map.resources :events, :collection => { :search => :get }
Moving these actions to an entirely separate controller might keep some of your controllers RESTful, but I find that keeping them in context is far more useful.
REST does not specify that you can't have additional views. No real world application is going to be able use only the supplied actions; this is why you can add your own actions.
REST is about being able to make stateless calls to the server. Your search action is stateless each time as the data so far is supplied back, correct? Your alternate display action is also stateless, just a different view.
As to if they should be manual routes or a new controller, that depends on how distinct the activity is. Your alternate view, if it provides a full set of CRUD (create, read, update, delete) operations would do well to be in a new controller. If you only have an alternate view to the data, I would just add an alternate view action.
In other words, it doesn't sound like your application is failing to be RESTful, it is more an issue of realizing that the automatically generated feature set is a starting point, not a conclusion.
In my opinion they may have gone a bit off the rails here. What happened to DRY?
I'm just getting back into Rails not having done much development with it since beta and I'm still waiting for the light-bulb to come on here. I'm still giving it a chance but if it hasn't happened for me by the end of my current project I'll probably just drop-back to the old standard routes and define the methods as I actually need them for the next one.
I won't go on to explain more about REST since I think that has been answered in this question, however I will talk a little bit about the default route.
My main problem with the default route is that if you have multiple sites using the same Rails app it can look horrible.
For example there may be controllers that you don't want people to be able to see on one app:
http://example1.somesite.com/example_2/foo/bar/1
compare this to
/:controller/:action/:id
This would go to the controller example_2/foo, action bar and id 1
I consider this to be the main flaw of Rails' default route and this is something that RESTful routes (with subdomain extensions) or only named routes (map.connect 'foo' ... ) can fix.
To remain RESTful in your design, you need to rethink what you call a resource.
In your example a show action for a search controller, (search resource) is the direction to remain restful.
In mine, I have a dashboard controller (show) and controllers for single fields of in-place ecditors (show and update)

Resources