aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/getting_started.md
diff options
context:
space:
mode:
Diffstat (limited to 'guides/source/getting_started.md')
-rw-r--r--guides/source/getting_started.md358
1 files changed, 233 insertions, 125 deletions
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 8966eef76a..d9619bbc21 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -89,9 +89,9 @@ Open up a command line prompt. On Mac OS X open Terminal.app, on Windows choose
dollar sign `$` should be run in the command line. Verify that you have a
current version of Ruby installed:
-TIP. A number of tools exist to help you quickly install Ruby and Ruby
+TIP: A number of tools exist to help you quickly install Ruby and Ruby
on Rails on your system. Windows users can use [Rails Installer](http://railsinstaller.org),
-while Mac OS X users can use [Rails One Click](http://railsoneclick.com).
+while Mac OS X users can use [Tokaido](https://github.com/tokaido/tokaidoapp).
```bash
$ ruby -v
@@ -122,10 +122,10 @@ To verify that you have everything installed correctly, you should be able to
run the following:
```bash
-$ rails --version
+$ bin/rails --version
```
-If it says something like "Rails 4.1.0", you are ready to continue.
+If it says something like "Rails 4.1.1", you are ready to continue.
### Creating the Blog Application
@@ -163,7 +163,7 @@ of the files and folders that Rails created by default:
| File/Folder | Purpose |
| ----------- | ------- |
|app/|Contains the controllers, models, views, helpers, mailers and assets for your application. You'll focus on this folder for the remainder of this guide.|
-|bin/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.|
+|bin/|Contains the rails script that starts your app and can contain other scripts you use to setup, deploy or run your application.|
|config/|Configure your application's routes, database, and more. This is covered in more detail in [Configuring Rails Applications](configuring.html).|
|config.ru|Rack configuration for Rack based servers used to start the application.|
|db/|Contains your current database schema, as well as the database migrations.|
@@ -190,7 +190,7 @@ start a web server on your development machine. You can do this by running the
following in the `blog` directory:
```bash
-$ rails server
+$ bin/rails server
```
TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the
@@ -243,7 +243,7 @@ tell it you want a controller called "welcome" with an action called "index",
just like this:
```bash
-$ rails generate controller welcome index
+$ bin/rails generate controller welcome index
```
Rails will create several files and a route for you.
@@ -267,8 +267,9 @@ invoke scss
create app/assets/stylesheets/welcome.css.scss
```
-Most important of these are of course the controller, located at `app/controllers/welcome_controller.rb`
-and the view, located at `app/views/welcome/index.html.erb`.
+Most important of these are of course the controller, located at
+`app/controllers/welcome_controller.rb` and the view, located at
+`app/views/welcome/index.html.erb`.
Open the `app/views/welcome/index.html.erb` file in your text editor. Delete all
of the existing code in the file, and replace it with the following single line
@@ -358,7 +359,7 @@ will be seen later, but for now notice that Rails has inferred the
singular form `article` and makes meaningful use of the distinction.
```bash
-$ rake routes
+$ bin/rake routes
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
@@ -396,7 +397,7 @@ a controller called `ArticlesController`. You can do this by running this
command:
```bash
-$ rails g controller articles
+$ bin/rails g controller articles
```
If you open up the newly generated `app/controllers/articles_controller.rb`
@@ -427,19 +428,22 @@ are generated in Rails they are empty by default, unless you tell it
your wanted actions during the generation process.
To manually define an action inside a controller, all you need to do is to
-define a new method inside the controller.
-Open `app/controllers/articles_controller.rb` and inside the `ArticlesController`
-class, define a `new` method like this:
+define a new method inside the controller. Open
+`app/controllers/articles_controller.rb` and inside the `ArticlesController`
+class, define a `new` method so that the controller now looks like this:
```ruby
-def new
+class ArticlesController < ApplicationController
+ def new
+ end
end
```
With the `new` method defined in `ArticlesController`, if you refresh
<http://localhost:3000/articles/new> you'll see another error:
-![Template is missing for articles/new](images/getting_started/template_is_missing_articles_new.png)
+![Template is missing for articles/new]
+(images/getting_started/template_is_missing_articles_new.png)
You're getting this error now because Rails expects plain actions like this one
to have views associated with them to display their information. With no view
@@ -552,7 +556,7 @@ To see what Rails will do with this, we look back at the output of
`rake routes`:
```bash
-$ rake routes
+$ bin/rake routes
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
@@ -565,18 +569,18 @@ edit_article GET /articles/:id/edit(.:format) articles#edit
root GET / welcome#index
```
-The `articles_path` helper tells Rails to point the form
-to the URI Pattern associated with the `articles` prefix; and
-the form will (by default) send a `POST` request
-to that route. This is associated with the
-`create` action of the current controller, the `ArticlesController`.
+The `articles_path` helper tells Rails to point the form to the URI Pattern
+associated with the `articles` prefix; and the form will (by default) send a
+`POST` request to that route. This is associated with the `create` action of
+the current controller, the `ArticlesController`.
With the form and its associated route defined, you will be able to fill in the
form and then click the submit button to begin the process of creating a new
article, so go ahead and do that. When you submit the form, you should see a
familiar error:
-![Unknown action create for ArticlesController](images/getting_started/unknown_action_create_for_articles.png)
+![Unknown action create for ArticlesController]
+(images/getting_started/unknown_action_create_for_articles.png)
You now need to create the `create` action within the `ArticlesController` for
this to work.
@@ -585,7 +589,7 @@ this to work.
To make the "Unknown action" go away, you can define a `create` action within
the `ArticlesController` class in `app/controllers/articles_controller.rb`,
-underneath the `new` action:
+underneath the `new` action, as shown:
```ruby
class ArticlesController < ApplicationController
@@ -632,13 +636,13 @@ parameters but nothing in particular is being done with them.
### Creating the Article model
-Models in Rails use a singular name, and their corresponding database tables use
-a plural name. Rails provides a generator for creating models, which
-most Rails developers tend to use when creating new models.
-To create the new model, run this command in your terminal:
+Models in Rails use a singular name, and their corresponding database tables
+use a plural name. Rails provides a generator for creating models, which most
+Rails developers tend to use when creating new models. To create the new model,
+run this command in your terminal:
```bash
-$ rails generate model Article title:string text:text
+$ bin/rails generate model Article title:string text:text
```
With that command we told Rails that we want a `Article` model, together
@@ -646,26 +650,23 @@ with a _title_ attribute of type string, and a _text_ attribute
of type text. Those attributes are automatically added to the `articles`
table in the database and mapped to the `Article` model.
-Rails responded by creating a bunch of files. For
-now, we're only interested in `app/models/article.rb` and
-`db/migrate/20140120191729_create_articles.rb` (your name could be a bit
-different). The latter is responsible
-for creating the database structure, which is what we'll look at next.
+Rails responded by creating a bunch of files. For now, we're only interested
+in `app/models/article.rb` and `db/migrate/20140120191729_create_articles.rb`
+(your name could be a bit different). The latter is responsible for creating
+the database structure, which is what we'll look at next.
-TIP: Active Record is smart enough to automatically map column names to
-model attributes, which means you don't have to declare attributes
-inside Rails models, as that will be done automatically by Active
-Record.
+TIP: Active Record is smart enough to automatically map column names to model
+attributes, which means you don't have to declare attributes inside Rails
+models, as that will be done automatically by Active Record.
### Running a Migration
-As we've just seen, `rails generate model` created a _database
-migration_ file inside the `db/migrate` directory.
-Migrations are Ruby classes that are designed to make it simple to
-create and modify database tables. Rails uses rake commands to run migrations,
-and it's possible to undo a migration after it's been applied to your database.
-Migration filenames include a timestamp to ensure that they're processed in the
-order that they were created.
+As we've just seen, `rails generate model` created a _database migration_ file
+inside the `db/migrate` directory. Migrations are Ruby classes that are
+designed to make it simple to create and modify database tables. Rails uses
+rake commands to run migrations, and it's possible to undo a migration after
+it's been applied to your database. Migration filenames include a timestamp to
+ensure that they're processed in the order that they were created.
If you look in the `db/migrate/20140120191729_create_articles.rb` file (remember,
yours will have a slightly different name), here's what you'll find:
@@ -690,13 +691,13 @@ in case you want to reverse it later. When you run this migration it will create
an `articles` table with one string column and a text column. It also creates
two timestamp fields to allow Rails to track article creation and update times.
-TIP: For more information about migrations, refer to [Rails Database
-Migrations](migrations.html).
+TIP: For more information about migrations, refer to [Rails Database Migrations]
+(migrations.html).
At this point, you can use a rake command to run the migration:
```bash
-$ rake db:migrate
+$ bin/rake db:migrate
```
Rails will execute this migration command and tell you it created the Articles
@@ -733,49 +734,47 @@ end
Here's what's going on: every Rails model can be initialized with its
respective attributes, which are automatically mapped to the respective
-database columns. In the first line we do just that
-(remember that `params[:article]` contains the attributes we're interested in).
-Then, `@article.save` is responsible for saving the model in the database.
-Finally, we redirect the user to the `show` action, which we'll define later.
+database columns. In the first line we do just that (remember that
+`params[:article]` contains the attributes we're interested in). Then,
+`@article.save` is responsible for saving the model in the database. Finally,
+we redirect the user to the `show` action, which we'll define later.
-TIP: As we'll see later, `@article.save` returns a boolean indicating
-whether the article was saved or not.
+TIP: As we'll see later, `@article.save` returns a boolean indicating whether
+the article was saved or not.
-If you now go to
-<http://localhost:3000/articles/new> you'll *almost* be able to create an
-article. Try it! You should get an error that looks like this:
+If you now go to <http://localhost:3000/articles/new> you'll *almost* be able
+to create an article. Try it! You should get an error that looks like this:
-![Forbidden attributes for new article](images/getting_started/forbidden_attributes_for_new_article.png)
+![Forbidden attributes for new article]
+(images/getting_started/forbidden_attributes_for_new_article.png)
Rails has several security features that help you write secure applications,
-and you're running into one of them now. This one is called
-`[strong_parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`,
-which requires us to tell Rails exactly which parameters are allowed into
-our controller actions.
-
-Why do you have to bother? The ability to grab and automatically assign
-all controller parameters to your model in one shot makes the programmer's
-job easier, but this convenience also allows malicious use. What if a
-request to the server was crafted to look like a new article form submit
-but also included extra fields with values that violated your applications
-integrity? They would be 'mass assigned' into your model and then into the
-database along with the good stuff - potentially breaking your application
-or worse.
-
-We have to whitelist our controller parameters to prevent wrongful
-mass assignment. In this case, we want to both allow and require the
-`title` and `text` parameters for valid use of `create`. The syntax for
-this introduces `require` and `permit`. The change will involve one line:
+and you're running into one of them now. This one is called `[strong_parameters]
+(http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`,
+which requires us to tell Rails exactly which parameters are allowed into our
+controller actions.
+
+Why do you have to bother? The ability to grab and automatically assign all
+controller parameters to your model in one shot makes the programmer's job
+easier, but this convenience also allows malicious use. What if a request to
+the server was crafted to look like a new article form submit but also included
+extra fields with values that violated your applications integrity? They would
+be 'mass assigned' into your model and then into the database along with the
+good stuff - potentially breaking your application or worse.
+
+We have to whitelist our controller parameters to prevent wrongful mass
+assignment. In this case, we want to both allow and require the `title` and
+`text` parameters for valid use of `create`. The syntax for this introduces
+`require` and `permit`. The change will involve one line in the `create` action:
```ruby
@article = Article.new(params.require(:article).permit(:title, :text))
```
-This is often factored out into its own method so it can be reused by
-multiple actions in the same controller, for example `create` and `update`.
-Above and beyond mass assignment issues, the method is often made
-`private` to make sure it can't be called outside its intended context.
-Here is the result:
+This is often factored out into its own method so it can be reused by multiple
+actions in the same controller, for example `create` and `update`. Above and
+beyond mass assignment issues, the method is often made `private` to make sure
+it can't be called outside its intended context. Here is the result:
```ruby
def create
@@ -792,13 +791,14 @@ private
```
TIP: For more information, refer to the reference above and
-[this blog article about Strong Parameters](http://weblog.rubyonrails.org/2012/3/21/strong-parameters/).
+[this blog article about Strong Parameters]
+(http://weblog.rubyonrails.org/2012/3/21/strong-parameters/).
### Showing Articles
-If you submit the form again now, Rails will complain about not finding
-the `show` action. That's not very useful though, so let's add the
-`show` action before proceeding.
+If you submit the form again now, Rails will complain about not finding the
+`show` action. That's not very useful though, so let's add the `show` action
+before proceeding.
As we have seen in the output of `rake routes`, the route for `show` action is
as follows:
@@ -813,10 +813,24 @@ parameter, which in our case will be the id of the article.
As we did before, we need to add the `show` action in
`app/controllers/articles_controller.rb` and its respective view.
+NOTE: A frequent practice is to place the standard CRUD actions in each
+controller in the following order: `index`, `show`, `new`, `edit`, `create`, `update`
+and `destroy`. You may use any order you choose, but keep in mind that these
+are public methods; as mentioned earlier in this guide, they must be placed
+before any private or protected method in the controller in order to work.
+
+Given that, let's add the `show` action, as follows:
+
```ruby
-def show
- @article = Article.find(params[:id])
-end
+class ArticlesController < ApplicationController
+ def show
+ @article = Article.find(params[:id])
+ end
+
+ def new
+ end
+
+ # snipped for brevity
```
A couple of things to note. We use `Article.find` to find the article we're
@@ -855,12 +869,24 @@ articles GET /articles(.:format) articles#index
```
Add the corresponding `index` action for that route inside the
-`ArticlesController` in the `app/controllers/articles_controller.rb` file:
+`ArticlesController` in the `app/controllers/articles_controller.rb` file.
+When we write an `index` action, the usual practice is to place it as the
+first method in the controller. Let's do it:
```ruby
-def index
- @articles = Article.all
-end
+class ArticlesController < ApplicationController
+ def index
+ @articles = Article.all
+ end
+
+ def show
+ @article = Article.find(params[:id])
+ end
+
+ def new
+ end
+
+ # snipped for brevity
```
And then finally, add the view for this action, located at
@@ -913,8 +939,8 @@ Let's add links to the other views as well, starting with adding this
This link will allow you to bring up the form that lets you create a new article.
-Also add a link in `app/views/articles/new.html.erb`, underneath the form, to
-go back to the `index` action:
+Now, add another link in `app/views/articles/new.html.erb`, underneath the
+form, to go back to the `index` action:
```erb
<%= form_for :article, url: articles_path do |f| %>
@@ -924,7 +950,7 @@ go back to the `index` action:
<%= link_to 'Back', articles_path %>
```
-Finally, add another link to the `app/views/articles/show.html.erb` template to
+Finally, add a link to the `app/views/articles/show.html.erb` template to
go back to the `index` action as well, so that people who are viewing a single
article can go back and view the whole list again:
@@ -942,9 +968,9 @@ article can go back and view the whole list again:
<%= link_to 'Back', articles_path %>
```
-TIP: If you want to link to an action in the same controller, you don't
-need to specify the `:controller` option, as Rails will use the current
-controller by default.
+TIP: If you want to link to an action in the same controller, you don't need to
+specify the `:controller` option, as Rails will use the current controller by
+default.
TIP: In development mode (which is what you're working in by default), Rails
reloads your application with every browser request, so there's no need to stop
@@ -1089,12 +1115,27 @@ you attempt to do just that on the new article form
We've covered the "CR" part of CRUD. Now let's focus on the "U" part, updating
articles.
-The first step we'll take is adding an `edit` action to the `ArticlesController`.
+The first step we'll take is adding an `edit` action to the `ArticlesController`,
+generally between the `new` and `create` actions, as shown:
```ruby
+def new
+ @article = Article.new
+end
+
def edit
@article = Article.find(params[:id])
end
+
+def create
+ @article = Article.new(article_params)
+
+ if @article.save
+ redirect_to @article
+ else
+ render 'new'
+ end
+end
```
The view will contain a form similar to the one we used when creating
@@ -1148,14 +1189,26 @@ via the `PATCH` HTTP method which is the HTTP method you're expected to use to
The first parameter of `form_for` can be an object, say, `@article` which would
cause the helper to fill in the form with the fields of the object. Passing in a
-symbol (`:article`) with the same name as the instance variable (`@article`) also
-automagically leads to the same behavior. This is what is happening here. More details
-can be found in [form_for documentation](http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for).
+symbol (`:article`) with the same name as the instance variable (`@article`)
+also automagically leads to the same behavior. This is what is happening here.
+More details can be found in [form_for documentation]
+(http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for).
-Next we need to create the `update` action in
-`app/controllers/articles_controller.rb`:
+Next, we need to create the `update` action in
+`app/controllers/articles_controller.rb`.
+Add it between the `create` action and the `private` method:
```ruby
+def create
+ @article = Article.new(article_params)
+
+ if @article.save
+ redirect_to @article
+ else
+ render 'new'
+ end
+end
+
def update
@article = Article.find(params[:id])
@@ -1215,8 +1268,8 @@ bottom of the template:
```html+erb
...
-<%= link_to 'Back', articles_path %>
-| <%= link_to 'Edit', edit_article_path(@article) %>
+<%= link_to 'Back', articles_path %> |
+<%= link_to 'Edit', edit_article_path(@article) %>
```
And here's how our app looks so far:
@@ -1225,10 +1278,10 @@ And here's how our app looks so far:
### Using partials to clean up duplication in views
-Our `edit` page looks very similar to the `new` page, in fact they
-both share the same code for displaying the form. Let's remove some duplication
-by using a view partial. By convention, partial files are prefixed by an
-underscore.
+Our `edit` page looks very similar to the `new` page; in fact, they
+both share the same code for displaying the form. Let's remove this
+duplication by using a view partial. By convention, partial files are
+prefixed by an underscore.
TIP: You can read more about partials in the
[Layouts and Rendering in Rails](layouts_and_rendering.html) guide.
@@ -1275,8 +1328,8 @@ The reason we can use this shorter, simpler `form_for` declaration
to stand in for either of the other forms is that `@article` is a *resource*
corresponding to a full set of RESTful routes, and Rails is able to infer
which URI and method to use.
-For more information about this use of `form_for`, see
-[Resource-oriented style](//api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for-label-Resource-oriented+style).
+For more information about this use of `form_for`, see [Resource-oriented style]
+(http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for-label-Resource-oriented+style).
Now, let's update the `app/views/articles/new.html.erb` view to use this new
partial, rewriting it completely:
@@ -1317,9 +1370,11 @@ people to craft malicious URLs like this:
<a href='http://example.com/articles/1/destroy'>look at this cat!</a>
```
-We use the `delete` method for destroying resources, and this route is mapped to
-the `destroy` action inside `app/controllers/articles_controller.rb`, which
-doesn't exist yet, but is provided below:
+We use the `delete` method for destroying resources, and this route is mapped
+to the `destroy` action inside `app/controllers/articles_controller.rb`, which
+doesn't exist yet. The `destroy` method is generally the last CRUD action in
+the controller, and like the other public CRUD actions, it must be placed
+before any `private` or `protected` methods. Let's add it:
```ruby
def destroy
@@ -1330,13 +1385,67 @@ def destroy
end
```
+The complete `ArticlesController` in the
+`app/controllers/articles_controller.rb` file should now look like this:
+
+```ruby
+class ArticlesController < ApplicationController
+ def index
+ @articles = Article.all
+ end
+
+ def show
+ @article = Article.find(params[:id])
+ end
+
+ def new
+ @article = Article.new
+ end
+
+ def edit
+ @article = Article.find(params[:id])
+ end
+
+ def create
+ @article = Article.new(article_params)
+
+ if @article.save
+ redirect_to @article
+ else
+ render 'new'
+ end
+ end
+
+ def update
+ @article = Article.find(params[:id])
+
+ if @article.update(article_params)
+ redirect_to @article
+ else
+ render 'edit'
+ end
+ end
+
+ def destroy
+ @article = Article.find(params[:id])
+ @article.destroy
+
+ redirect_to articles_path
+ end
+
+ private
+ def article_params
+ params.require(:article).permit(:title, :text)
+ end
+end
+```
+
You can call `destroy` on Active Record objects when you want to delete
them from the database. Note that we don't need to add a view for this
action since we're redirecting to the `index` action.
Finally, add a 'Destroy' link to your `index` action template
-(`app/views/articles/index.html.erb`) to wrap everything
-together.
+(`app/views/articles/index.html.erb`) to wrap everything together.
```html+erb
<h1>Listing Articles</h1>
@@ -1376,9 +1485,8 @@ Without this file, the confirmation dialog box wouldn't appear.
Congratulations, you can now create, show, list, update and destroy
articles.
-TIP: In general, Rails encourages the use of resources objects in place
-of declaring routes manually.
-For more information about routing, see
+TIP: In general, Rails encourages using resources objects instead of
+declaring routes manually. For more information about routing, see
[Rails Routing from the Outside In](routing.html).
Adding a Second Model
@@ -1394,7 +1502,7 @@ the `Article` model. This time we'll create a `Comment` model to hold
reference of article comments. Run this command in your terminal:
```bash
-$ rails generate model Comment commenter:string body:text article:references
+$ bin/rails generate model Comment commenter:string body:text article:references
```
This command will generate four files:
@@ -1442,7 +1550,7 @@ the two models. An index for this association is also created on this column.
Go ahead and run the migration:
```bash
-$ rake db:migrate
+$ bin/rake db:migrate
```
Rails is smart enough to only execute the migrations that have not already been
@@ -1518,7 +1626,7 @@ With the model in hand, you can turn your attention to creating a matching
controller. Again, we'll use the same generator we used before:
```bash
-$ rails generate controller Comments
+$ bin/rails generate controller Comments
```
This creates six files and one empty directory:
@@ -1840,7 +1948,7 @@ database and send us back to the show action for the article.
### Deleting Associated Objects
If you delete an article, its associated comments will also need to be
-deleted. Otherwise they would simply occupy space in the database. Rails allows
+deleted, otherwise they would simply occupy space in the database. Rails allows
you to use the `dependent` option of an association to achieve this. Modify the
Article model, `app/models/article.rb`, as follows:
@@ -1895,7 +2003,7 @@ class CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
- ...
+ # ...
end
# snipped for brevity