Hey, i have some experience with MVC. but I'm new to rails. I'm using the scaffold command to generate some default files. The model looks clean and nice, but the controller and the views aren't really dry. The contents of new.html.erb and edit.html.erb are almost the same and the methods new/edit and create/update are doing almost the same thing. In other frameworks i've used only one view for updating and creating new entries and also the same method in my controller by setting the id as an optional parameter. Do they use this structure to keep things RESTful (i have not much of a clue about rest :()? Is it the best practice to use this default stuff for crud?
The scaffold generator is a pretty good place to start. As you pointed out, there are some things which are not that great about it. I think most people take what the scaffold generates and then fix it up to their liking. For example, you can extract the form part from new.html.erb and edit.html.erb and place it in a partial _form.html.erb. Then update new.html.erb and edit.html.erb to include that partial to render the form. I think that for Rails 3, the scaffold generator has been changed to do this by default.
It does seem like new and edit, and create and update are pretty much the same, but you need to remember that they are mapped to different HTTP methods and URLs, which ties in to the whole RESTful resource idea. Check out the RailsGuides for routing, the section CRUD, Verbs, and Actions has a nice table of the seven different routes and the differences between them.
You should check out ryanb's nifty-generators:
http://github.com/ryanb/nifty-generators
The scaffolding creates a partial view called _form that then gets referenced from the new and edit views. It also comes with a bunch of other nice options -- like generating your views in haml or your tests in Shoulda or RSpec.
If they wanted you to keep it they wouldn't call it "scaffolding." It's just there to make everything work out of the box. If you put it into production you will more than likely be laughed at.
Related
I'm still fairly new to rails, but I've been trying to figure it out by building a bunch of simple projects like blogs, forums, clones over the weekend.
One of the blogs that I'm working on is a typical blog with users(devise), posts, and comments. I've been following a tutorial for this.
The thing that I've been really confuse on is setting up the comments and rendering it.
The tutorial teaches me to make a partial for comment in the comment view named _comment.html.erb and then another for form _form.html.erb . I fully understand that to call the form i just do render 'comments/form' but for the comment.html.erb i need to render #post.comments how come it's not 'comments/comment'? Why is it comments with the S?
I've tried reading up on render and plurization on rails, but most of them just talk about the model.
There are two convention over configuration things going on here that may be causing you some confusion but are meant to save time.
Rails will automagically find the right partial if it follows naming conventions, meaning if your model is Comment that the view partial is located in app/views/comments/_comment.html.erb. That means you don't have to specify the location of the partial when calling render, but instead can just pass the model object directly and Rails figures out that you want it to render the partial and finds it on its own.
The reason it's comments plural here is that you are rendering all of the comments as a collection, not just a single comment. It's a convenience feature to allow the developer to simply tell Rails to render a collection and it will automagically know to use the corresponding partial. It's identical to typing:
#post.comments.each do |comment|
render 'comments/comment`, object: comment
end
Note how the above code is calling render directly on a model object so we don't have to bother specifying the location of the partial (again, assuming you followed the convention when naming and locating things). If we named the partial something else, then we'd have to specify the location like your other examples.
I'm learning RoR, and I'm getting very confused by the "_path" method as it's used in Controllers and Routes. To be more specific, I'm referring to the many different calls that take the syntax "(something)_path". So far as I know, they all seem to either encode or manipulate a URL or link. I'm having a hard time mastering the use of this type of method because I can't figure out what it's core functionality is supposed to be.
For example, I could use the following code to redirect an old URL structure to a page of listed Tweet instances in my config/routes.rb file:
get '/all' => 'tweets#index', as: 'all_tweets'
Only now can I use the following in an .erb file. Notice the "_path" code at the end of the line.
<%= link_to "All Tweets", all_tweets_path %>
I could also use the following code to create a link to an edit page (and another action) in a different .erb file:
<p><%= link_to tweet.user.name, edit_tweet_path(#tweet) %></p>
I've tried reading through my study materials as well as the RoR documentation, but I always end up more lost than when I began. Does anybody know the low-level definition of this "_path" method?
Helper
It's called a route helper, which means that Rails will generate them to help provide you with resource-based routing structures. I'll explain more in a second
--
To explain properly - Rails is just a framework.
Like all software, it is a series of files loaded in a particular order. As such, Rails creates a series of helper methods in the booting process. These "helper" methods can then be used throughout your application to call functionality / information as you require:
The Rails framework provides a large number of helpers for working
with assets, dates, forms, numbers and model objects, to name a few.
These helpers are available to all templates by default.
In addition to using the standard template helpers provided, creating
custom helpers to extract complicated logic or reusable functionality
is strongly encouraged. By default, each controller will include all
helpers. These helpers are only accessible on the controller through
.helpers
The route helpers (which are generated from your config/routes.rb file give you the ability to call routes which are resourceful. These might seem strange to begin with, but once you understand them, will help you inexorably.
--
Resourceful
To give you more clarity - Rails routes are known as resourceful
This means they are constructed around resources. To give you a brief definition of this, you need to appreciate that the resources of your application are the pools of data you can add to, and pull
from.
To explain further, because Rails is object orientated. If you're new, this won't mean very much, but keep it in mind, as when you progress through the language / work, you'll begin to see why this is important.
Object orientated programming puts OBJECTS at the center of the flow. Typically, you'd put logic at the center, but with OOP, it's the objects. This is very important for us, as it means that everything you do in Rails is based around the objects you can create.
As per the MVC principle (which, again, is what Rails is built on), you'll create / invoke your objects from your Models:
This means that if you want to create a series of routes to "CRUD" (Create Read Update Destroy) your objects, Rails is able to create the routes necessary to do that. This is where the resources directives come from inside the routes file:
Hope this helps!
Actually, these paths are generated based on your routes.rb. If you run this command at your project, you would be able to see all available on your app
rake routes
For example, if I declare my resources in routes.rb like this
resources :posts
then I would automatically have following available paths
posts_path
post_path
new_post_path
edit_post_path
If you use some strange abc_path which has not been declared in routes.rb, then you will get errors.
Hope this is helpful, you will definitely need to work more with Rails and then eventually you will understand all of these things :)
you could find definition for these methods in rails repository:
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set.rb#L127
I want to create own customized generator for scafflod so that i can change the default layout of generated .html.erb or .html.haml for a particular application.
I want to customize the layouts
Making generators is a good idea when you want a specific layout applied to few of your resources. It might be like you have an normal user section and admin user section with different layouts.
You may have a good reference of making a generator from here:http://railscasts.com/episodes/218-making-generators-in-rails-3?view=asciicast
There is some pretty nice stuff you can do with this. Problem is it is very badly documented, but once you know where to store the various template files, you're on the move:
It all starts in lib/templates
lib/templates/active_record/model/model.rb contains the model template
lib/templates/factory_girl/model/fixtures.erb contains the factory girl template
lib/templates/rails/scaffold_controller/controller.rb the controller
lib/templates/rspec/model/model_spec.rb the rspec model
lib/templates/rspec/scaffold/controller_spec.rb the rspec controller
lib/templates/haml/scaffold/_form.html.haml the views (idem dito for edit, index, new and show)
If you need more info on the templates, just let me know!
I am having trouble figuring out how to make my rails app work with a central dashboard. Basically I want it to work so that when a user clicks on a course from the list, the details of the course are loaded into the dashboard. The ajax part isn't too complicated, I am however struggling slightly with loading the partial in when ajax isn't being used. I figure I can simply put some logic in the view so that if #course != null it will load the partial.
The routes are also giving me a bit of difficulty. So I wanted the url to resemble the following: dashboard/student/:id/university/:id/course/:id
I came up with the following, but is there a better way?
http://pastebin.com/keEmaznw
It's hard to understand your question. You've given us scant detail, and insufficient code. That said, regarding loading a partial with a nil object:
If you pass an object to a partial, Rails will take care of the rendering for you automatically, and no nil (instead of null, in Ruby talk) check is necessary:
= render #object
Regarding routes, yes, there is a better way: You should generally avoid nesting your routes more than two levels. This becomes a nightmare to test, and you end up writing very long method names:
edit_dashboard_student_university_course_path(#university, #course, #student)
You really don't want to be writing that in your view or your tests. think about it, if you want to edit a student, is it necessary to load the university and the course as well?
I am working on a rails 3.2 application that has a lot of static, deeply nested pages. The architecture is as follows:
So far, I have an information controller with these four methods:
about_the_liver
therapies
nutrition
liver_diseases
with the following routes:
get "information/therapies"
get "information/nutrition"
get "information/liver_diseases"
get "information/about_the_liver"
Here are my questions:
First of all, these routes, as generated by the rails generator, look clumsy. Is there any way to dry them out and group them together? E.g., so that the "information/" part is not repeated so often?
I have come up with this, but I am not sure whether this is the best approach:
[ :therapies, :nutrition, :liver_diseases, :about_the_liver ].each do |method|
get "information/#{method}"
end
I will need views for every single menu entry that you can see in the rightmost menu. My approach is to change liver_diseases to being a separate controller and have 8 different views - but that can't be dry. Is there a "rails way" to this?
Couldn't you simply put your static pages in /public and have them served directly from there? If there's no rails content this would be the quickest and most efficient approach.