diff options
Diffstat (limited to 'guides/source/getting_started.md')
-rw-r--r-- | guides/source/getting_started.md | 187 |
1 files changed, 97 insertions, 90 deletions
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index fe01088b2e..65fdd7ca0d 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -23,9 +23,12 @@ application from scratch. It does not assume that you have any prior experience with Rails. However, to get the most out of it, you need to have some prerequisites installed: -* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer. -* The [RubyGems](https://rubygems.org) packaging system, which is installed with Ruby - versions 1.9 and later. To learn more about RubyGems, please read the [RubyGems Guides](http://guides.rubygems.org). +* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 2.2.2 or newer. +* Right version of [Development Kit](http://rubyinstaller.org/downloads/), if you + are using Windows. +* The [RubyGems](https://rubygems.org) packaging system, which is installed with + Ruby by default. To learn more about RubyGems, please read the + [RubyGems Guides](http://guides.rubygems.org). * A working installation of the [SQLite3 Database](https://www.sqlite.org). Rails is a web application framework running on the Ruby programming language. @@ -34,7 +37,7 @@ curve diving straight into Rails. There are several curated lists of online reso for learning Ruby: * [Official Ruby Programming Language website](https://www.ruby-lang.org/en/documentation/) -* [reSRC's List of Free Programming Books](http://resrc.io/list/10/list-of-free-programming-books/#ruby) +* [List of Free Programming Books](https://github.com/vhf/free-programming-books/blob/master/free-programming-books.md#ruby) Be aware that some resources, while still excellent, cover versions of Ruby as old as 1.6, and commonly 1.8, and will not include some syntax that you will see in day-to-day @@ -50,7 +53,7 @@ code while accomplishing more than many other languages and frameworks. Experienced Rails developers also report that it makes web application development more fun. -Rails is opinionated software. It makes the assumption that there is the "best" +Rails is opinionated software. It makes the assumption that there is a "best" way to do things, and it's designed to encourage that way - and in some cases to discourage alternatives. If you learn "The Rails Way" you'll probably discover a tremendous increase in productivity. If you persist in bringing old habits from @@ -69,10 +72,9 @@ The Rails philosophy includes two major guiding principles: Creating a New Rails Project ---------------------------- - -The best way to use this guide is to follow each step as it happens, no code or -step needed to make this example application has been left out, so you can -literally follow along step by step. +The best way to read this guide is to follow it step by step. All steps are +essential to run this example application and no additional code or steps are +needed. By following along with this guide, you'll create a Rails project called `blog`, a (very) simple weblog. Before you can start building the application, @@ -89,17 +91,17 @@ 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: +```bash +$ ruby -v +ruby 2.3.1p112 +``` + 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 [Tokaido](https://github.com/tokaido/tokaidoapp). For more installation methods for most Operating Systems take a look at [ruby-lang.org](https://www.ruby-lang.org/en/documentation/installation/). -```bash -$ ruby -v -ruby 2.0.0p353 -``` - Many popular UNIX-like OSes ship with an acceptable version of SQLite3. On Windows, if you installed Rails through Rails Installer, you already have SQLite installed. Others can find installation instructions @@ -162,8 +164,8 @@ 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 setup, deploy or run your application.| +|app/|Contains the controllers, models, views, helpers, mailers, channels, jobs 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 setup, update, 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.| @@ -172,7 +174,7 @@ of the files and folders that Rails created by default: |log/|Application log files.| |public/|The only folder seen by the world as-is. Contains static files and compiled assets.| |Rakefile|This file locates and loads tasks that can be run from the command line. The task definitions are defined throughout the components of Rails. Rather than changing Rakefile, you should add your own tasks by adding files to the lib/tasks directory of your application.| -|README.rdoc|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.| +|README.md|This is a brief instruction manual for your application. You should edit this file to tell others what your application does, how to set it up, and so on.| |test/|Unit tests, fixtures, and other test apparatus. These are covered in [Testing Rails Applications](testing.html).| |tmp/|Temporary files (like cache and pid files).| |vendor/|A place for all third-party code. In a typical Rails application this includes vendored gems.| @@ -206,7 +208,7 @@ commented line for new apps and you can uncomment if you need it. default to the `Gemfile` in apps generated under JRuby. You can investigate all the supported runtimes at [ExecJS](https://github.com/rails/execjs#readme). -This will fire up WEBrick, a web server distributed with Ruby by default. To see +This will fire up Puma, a web server distributed with Rails by default. To see your application in action, open a browser window and navigate to <http://localhost:3000>. You should see the Rails default information page: @@ -221,8 +223,7 @@ the server. The "Welcome aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a -page. You can also click on the _About your application's environment_ link to -see a summary of your application's environment. +page. ### Say "Hello", Rails @@ -243,11 +244,11 @@ Ruby) which is processed by the request cycle in Rails before being sent to the user. To create a new controller, you will need to run the "controller" generator and -tell it you want a controller called "welcome" with an action called "index", +tell it you want a controller called "Welcome" with an action called "index", just like this: ```bash -$ bin/rails generate controller welcome index +$ bin/rails generate controller Welcome index ``` Rails will create several files and a route for you. @@ -262,6 +263,7 @@ invoke test_unit create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb +invoke test_unit invoke assets invoke coffee create app/assets/javascripts/welcome.coffee @@ -296,32 +298,37 @@ Open the file `config/routes.rb` in your editor. Rails.application.routes.draw do get 'welcome/index' - # The priority is based upon order of creation: - # first created -> highest priority. - # - # You can have the root of your site routed with "root" - # root 'welcome#index' - # - # ... + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + # Serve websocket cable requests in-process + # mount ActionCable.server => '/cable' +end ``` This is your application's _routing file_ which holds entries in a special [DSL (domain-specific language)](http://en.wikipedia.org/wiki/Domain-specific_language) that tells Rails how to connect incoming requests to -controllers and actions. This file contains many sample routes on commented -lines, and one of them actually shows you how to connect the root of your site -to a specific controller and action. Find the line beginning with `root` and -uncomment it. It should look something like the following: +controllers and actions. +Edit this file by adding the line of code `root 'welcome#index'`. +It should look something like the following: ```ruby -root 'welcome#index' +Rails.application.routes.draw do + get 'welcome/index' + + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + # Serve websocket cable requests in-process + # mount ActionCable.server => '/cable' + root 'welcome#index' +end ``` `root 'welcome#index'` tells Rails to map requests to the root of the application to the welcome controller's index action and `get 'welcome/index'` tells Rails to map requests to <http://localhost:3000/welcome/index> to the welcome controller's index action. This was created earlier when you ran the -controller generator (`bin/rails generate controller welcome index`). +controller generator (`bin/rails generate controller Welcome index`). Launch the web server again if you stopped it to generate the controller (`bin/rails server`) and navigate to <http://localhost:3000> in your browser. You'll see the @@ -345,7 +352,7 @@ operations are referred to as _CRUD_ operations. Rails provides a `resources` method which can be used to declare a standard REST resource. You need to add the _article resource_ to the -`config/routes.rb` as follows: +`config/routes.rb` so the file will look as follows: ```ruby Rails.application.routes.draw do @@ -356,13 +363,13 @@ Rails.application.routes.draw do end ``` -If you run `bin/rake routes`, you'll see that it has defined routes for all the +If you run `bin/rails routes`, you'll see that it has defined routes for all the standard RESTful actions. The meaning of the prefix column (and other columns) will be seen later, but for now notice that Rails has inferred the singular form `article` and makes meaningful use of the distinction. ```bash -$ bin/rake routes +$ bin/rails routes Prefix Verb URI Pattern Controller#Action articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create @@ -377,14 +384,14 @@ edit_article GET /articles/:id/edit(.:format) articles#edit In the next section, you will add the ability to create new articles in your application and be able to view them. This is the "C" and the "R" from CRUD: -creation and reading. The form for doing this will look like this: +create and read. The form for doing this will look like this:  It will look a little basic for now, but that's ok. We'll look at improving the styling for it afterwards. -### Laying down the ground work +### Laying down the groundwork Firstly, you need a place within the application to create a new article. A great place for that would be at `/articles/new`. With the route already @@ -400,7 +407,7 @@ a controller called `ArticlesController`. You can do this by running this command: ```bash -$ bin/rails g controller articles +$ bin/rails generate controller Articles ``` If you open up the newly generated `app/controllers/articles_controller.rb` @@ -468,7 +475,7 @@ one here because the `ArticlesController` inherits from `ApplicationController`. The next part of the message contains a hash. The `:locale` key in this hash simply indicates which spoken language template should be retrieved. By default, this is the English - or "en" - template. The next key, `:formats` specifies the -format of template to be served in response. The default format is `:html`, and +format of the template to be served in response. The default format is `:html`, and so Rails is looking for an HTML template. The final key, `:handlers`, is telling us what _template handlers_ could be used to render our template. `:erb` is most commonly used for HTML templates, `:builder` is used for XML templates, and @@ -556,10 +563,10 @@ this: In this example, the `articles_path` helper is passed to the `:url` option. To see what Rails will do with this, we look back at the output of -`bin/rake routes`: +`bin/rails routes`: ```bash -$ bin/rake routes +$ bin/rails routes Prefix Verb URI Pattern Controller#Action articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create @@ -619,10 +626,10 @@ def create end ``` -The `render` method here is taking a very simple hash with a key of `plain` and +The `render` method here is taking a very simple hash with a key of `:plain` and value of `params[:article].inspect`. The `params` method is the object which represents the parameters (or fields) coming in from the form. The `params` -method returns an `ActiveSupport::HashWithIndifferentAccess` object, which +method returns an `ActionController::Parameters` object, which allows you to access the keys of the hash using either strings or symbols. In this situation, the only parameters that matter are the ones from the form. @@ -632,7 +639,7 @@ If you re-submit the form one more time you'll now no longer get the missing template error. Instead, you'll see something that looks like the following: ```ruby -{"title"=>"First article!", "text"=>"This is my first article."} +<ActionController::Parameters {"title"=>"First Article!", "text"=>"This is my first article."} permitted: false> ``` This action is now displaying the parameters for the article that are coming in @@ -650,7 +657,7 @@ run this command in your terminal: $ bin/rails generate model Article title:string text:text ``` -With that command we told Rails that we want a `Article` model, together +With that command we told Rails that we want an `Article` model, together 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. @@ -677,13 +684,13 @@ If you look in the `db/migrate/YYYYMMDDHHMMSS_create_articles.rb` file (remember, yours will have a slightly different name), here's what you'll find: ```ruby -class CreateArticles < ActiveRecord::Migration +class CreateArticles < ActiveRecord::Migration[5.0] def change create_table :articles do |t| t.string :title t.text :text - t.timestamps null: false + t.timestamps end end end @@ -699,10 +706,10 @@ 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). -At this point, you can use a rake command to run the migration: +At this point, you can use a bin/rails command to run the migration: ```bash -$ bin/rake db:migrate +$ bin/rails db:migrate ``` Rails will execute this migration command and tell you it created the Articles @@ -719,7 +726,7 @@ NOTE. Because you're working in the development environment by default, this command will apply to the database defined in the `development` section of your `config/database.yml` file. If you would like to execute migrations in another environment, for instance in production, you must explicitly pass it when -invoking the command: `bin/rake db:migrate RAILS_ENV=production`. +invoking the command: `bin/rails db:migrate RAILS_ENV=production`. ### Saving data in the controller @@ -764,7 +771,7 @@ 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 +extra fields with values that violated your application's 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. @@ -806,7 +813,7 @@ 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 `bin/rake routes`, the route for `show` action is +As we have seen in the output of `bin/rails routes`, the route for `show` action is as follows: ``` @@ -836,7 +843,7 @@ class ArticlesController < ApplicationController def new end - # snipped for brevity + # snippet for brevity ``` A couple of things to note. We use `Article.find` to find the article we're @@ -868,7 +875,7 @@ Visit <http://localhost:3000/articles/new> and give it a try! ### Listing all articles We still need a way to list all our articles, so let's do that. -The route for this as per output of `bin/rake routes` is: +The route for this as per output of `bin/rails routes` is: ``` articles GET /articles(.:format) articles#index @@ -892,7 +899,7 @@ class ArticlesController < ApplicationController def new end - # snipped for brevity + # snippet for brevity ``` And then finally, add the view for this action, located at @@ -988,21 +995,22 @@ and restart the web server when a change is made. The model file, `app/models/article.rb` is about as simple as it can get: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord end ``` There isn't much to this file - but note that the `Article` class inherits from -`ActiveRecord::Base`. Active Record supplies a great deal of functionality to -your Rails models for free, including basic database CRUD (Create, Read, Update, -Destroy) operations, data validation, as well as sophisticated search support -and the ability to relate multiple models to one another. +`ApplicationRecord`. `ApplicationRecord` inherits from `ActiveRecord::Base` +which supplies a great deal of functionality to your Rails models for free, +including basic database CRUD (Create, Read, Update, Destroy) operations, data +validation, as well as sophisticated search support and the ability to relate +multiple models to one another. Rails includes methods to help you validate the data that you send to models. Open the `app/models/article.rb` file and edit it: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord validates :title, presence: true, length: { minimum: 5 } end @@ -1240,10 +1248,9 @@ article we want to show the form back to the user. We reuse the `article_params` method that we defined earlier for the create action. -TIP: You don't need to pass all attributes to `update`. For -example, if you'd call `@article.update(title: 'A new title')` -Rails would only update the `title` attribute, leaving all other -attributes untouched. +TIP: It is not necessary to pass all the attributes to `update`. For example, +if `@article.update(title: 'A new title')` was called, Rails would only update +the `title` attribute, leaving all other attributes untouched. Finally, we want to show a link to the `edit` action in the list of all the articles, so let's add that now to `app/views/articles/index.html.erb` to make @@ -1363,7 +1370,7 @@ Then do the same for the `app/views/articles/edit.html.erb` view: We're now ready to cover the "D" part of CRUD, deleting articles from the database. Following the REST convention, the route for -deleting articles as per output of `bin/rake routes` is: +deleting articles as per output of `bin/rails routes` is: ```ruby DELETE /articles/:id(.:format) articles#destroy @@ -1491,7 +1498,7 @@ appear.  TIP: Learn more about jQuery Unobtrusive Adapter (jQuery UJS) on -[Working With Javascript in Rails](working_with_javascript_in_rails.html) guide. +[Working With JavaScript in Rails](working_with_javascript_in_rails.html) guide. Congratulations, you can now create, show, list, update and destroy articles. @@ -1510,7 +1517,7 @@ comments on articles. We're going to see the same generator that we used before when creating the `Article` model. This time we'll create a `Comment` model to hold -reference of article comments. Run this command in your terminal: +reference to an article. Run this command in your terminal: ```bash $ bin/rails generate model Comment commenter:string body:text article:references @@ -1522,13 +1529,13 @@ This command will generate four files: | -------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | db/migrate/20140120201010_create_comments.rb | Migration to create the comments table in your database (your name will include a different timestamp) | | app/models/comment.rb | The Comment model | -| test/models/comment_test.rb | Testing harness for the comments model | +| test/models/comment_test.rb | Testing harness for the comment model | | test/fixtures/comments.yml | Sample comments for use in testing | First, take a look at `app/models/comment.rb`: ```ruby -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord belongs_to :article end ``` @@ -1537,32 +1544,34 @@ This is very similar to the `Article` model that you saw earlier. The difference is the line `belongs_to :article`, which sets up an Active Record _association_. You'll learn a little about associations in the next section of this guide. +The (`:references`) keyword used in the bash command is a special data type for models. +It creates a new column on your database table with the provided model name appended with an `_id` +that can hold integer values. You can get a better understanding after analyzing the +`db/schema.rb` file below. + In addition to the model, Rails has also made a migration to create the corresponding database table: ```ruby -class CreateComments < ActiveRecord::Migration +class CreateComments < ActiveRecord::Migration[5.0] def change create_table :comments do |t| t.string :commenter t.text :body + t.references :article, foreign_key: true - # this line adds an integer column called `article_id`. - t.references :article, index: true - - t.timestamps null: false + t.timestamps end - add_foreign_key :comments, :articles end end ``` -The `t.references` line sets up a foreign key column for the association between -the two models. An index for this association is also created on this column. -Go ahead and run the migration: +The `t.references` line creates an integer column called `article_id`, an index +for it, and a foreign key constraint that points to the `id` column of the `articles` +table. Go ahead and run the migration: ```bash -$ bin/rake db:migrate +$ bin/rails db:migrate ``` Rails is smart enough to only execute the migrations that have not already been @@ -1572,8 +1581,6 @@ run against the current database, so in this case you will just see: == CreateComments: migrating ================================================= -- create_table(:comments) -> 0.0115s --- add_foreign_key(:comments, :articles) - -> 0.0000s == CreateComments: migrated (0.0119s) ======================================== ``` @@ -1591,7 +1598,7 @@ association. You've already seen the line of code inside the `Comment` model (app/models/comment.rb) that makes each comment belong to an Article: ```ruby -class Comment < ActiveRecord::Base +class Comment < ApplicationRecord belongs_to :article end ``` @@ -1600,7 +1607,7 @@ You'll need to edit `app/models/article.rb` to add the other side of the association: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord has_many :comments validates :title, presence: true, length: { minimum: 5 } @@ -1966,7 +1973,7 @@ you to use the `dependent` option of an association to achieve this. Modify the Article model, `app/models/article.rb`, as follows: ```ruby -class Article < ActiveRecord::Base +class Article < ApplicationRecord has_many :comments, dependent: :destroy validates :title, presence: true, length: { minimum: 5 } @@ -2003,7 +2010,7 @@ class ArticlesController < ApplicationController @articles = Article.all end - # snipped for brevity + # snippet for brevity ``` We also want to allow only authenticated users to delete comments, so in the @@ -2019,7 +2026,7 @@ class CommentsController < ApplicationController # ... end - # snipped for brevity + # snippet for brevity ``` Now if you try to create a new article, you will be greeted with a basic HTTP |