Author |
Topic: Rails Probject II-- Blog |
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Rails Probject II-- Blog |
Prerequisites
Rails is a web application framework running on the Ruby programming language. In order to create a new Rails project, you need to have some prerequisites installed.
Database -- which is used to store Rails project's objects. NodeJS -- a JavaScript runtime Bundler -- which is used to manage project's version control.
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
MVC (Model-View-Controller) |
Rails framework follows the MVC philosophy:
+-----------+
| View | /app/views/
+-----------+
|
|
|
+------------+ +-----------+
client ----> routes ---> | Controller |----------------| Model | /app/models/
+------------+ +-----------+
/onfig/routes.rb /app/controllers/ |
|
------
| DB |
------
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 1 -- Create a Rails project container |
-- administrator@ubuntu:~$ rails new blog
create
create README.md
create Rakefile
create config.ru
create .gitignore
create Gemfile
run git init from "."
Initialized empty Git repository in /home/administrator/blog/.git/
create app
create app/assets/config/manifest.js
create app/assets/javascripts/application.js
create app/assets/javascripts/cable.js
create app/assets/stylesheets/application.css
create app/channels/application_cable/channel.rb
create app/channels/application_cable/connection.rb
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/jobs/application_job.rb
create app/mailers/application_mailer.rb
create app/models/application_record.rb
create app/views/layouts/application.html.erb
create app/views/layouts/mailer.html.erb
create app/views/layouts/mailer.text.erb
create app/assets/images/.keep
create app/assets/javascripts/channels
create app/assets/javascripts/channels/.keep
create app/controllers/concerns/.keep
create app/models/concerns/.keep
create bin
create bin/bundle
create bin/rails
create bin/rake
create bin/setup
create bin/update
create bin/yarn
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/secrets.yml
create config/cable.yml
create config/puma.rb
create config/spring.rb
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/application_controller_renderer.rb
create config/initializers/assets.rb
create config/initializers/backtrace_silencers.rb
create config/initializers/cookies_serializer.rb
create config/initializers/cors.rb
create config/initializers/filter_parameter_logging.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/new_framework_defaults_5_1.rb
create config/initializers/wrap_parameters.rb
create config/locales
create config/locales/en.yml
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create lib
create lib/tasks
create lib/tasks/.keep
create lib/assets
create lib/assets/.keep
create log
create log/.keep
create public
create public/404.html
create public/422.html
create public/500.html
create public/apple-touch-icon-precomposed.png
create public/apple-touch-icon.png
create public/favicon.ico
create public/robots.txt
create test/fixtures
create test/fixtures/.keep
create test/fixtures/files
create test/fixtures/files/.keep
create test/controllers
create test/controllers/.keep
create test/mailers
create test/mailers/.keep
create test/models
create test/models/.keep
create test/helpers
create test/helpers/.keep
create test/integration
create test/integration/.keep
create test/test_helper.rb
create test/system
create test/system/.keep
create test/application_system_test_case.rb
create tmp
create tmp/.keep
create tmp/cache
create tmp/cache/assets
create vendor
create vendor/.keep
create package.json
remove config/initializers/cors.rb
remove config/initializers/new_framework_defaults_5_1.rb
run bundle install
This will create a Rails application called blog in a blog directory with all necessary folders and files generated.
Among them, the most important ones are: config -- the directory with configuration files, e.g. routes.rb app/controllers -- the directory holding controllers app/models -- the directory holding models app/views -- the directory holding views
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 2 -- Create a controller |
-- administrator@ubuntu:$ cd blog
-- administrator@ubuntu:~/blog$ rails generate controller Welcome index
Running via Spring preloader in process 69075
create app/controllers/welcome_controller.rb
route get 'welcome/index'
invoke erb
create app/views/welcome
create app/views/welcome/index.html.erb
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
invoke scss
create app/assets/stylesheets/welcome.scss
This generated: app/controllers/welcome_controller.rb -- a controller Welcome with action index
class WelcomeController < ApplicationController
def index
end
end
app/views/welcome/index.html.erb -- a view associated with controller Welcome and its action index
<h1>Welcome#index</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
a routing instruction added into routing table config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Here, get 'welcome/index' maps the GET request http://<host>/welcome/index(or index.html) to controller welcome and action index.
The root request http://<host>/ is routed to the default "Rails Welcome Aboard!" page. If you want to map the root request to controller welcome and action index. You can add root 'welcome#index':
Rails.application.routes.draw do
get 'welcome/index'
root 'welcome#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Traffic flow |
/config/routes.rb app/controllers/welcome_controller.rb
http://localhost:3000/ --------------------> ---------------------------------------->
^ ^
| |
root 'welcome#index' def index
// default to view --> app/views/welcome/index.html.erb
end
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 3 -- Create a new resource |
What is resource? A resource is the term used for a collection of similar objects, such as organization, people or books. You can create, read, update and destroy items for a resource and these operations are referred to as CRUD operations.
Rails provides a resources method which can be used to declare a standard REST resource. For example, you can add a posts resource to the config/routes.rb for your blog.
Rails.application.routes.draw do
get 'welcome/index'
resources :posts
root 'welcome#index'
end
And then run:
administrator@ubuntu:~/blog$ rails routes
Prefix Verb URI Pattern Controller#Action
welcome_index GET /welcome/index(.:format) welcome#index
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root GET / welcome#index
This shows that you have a complete CRUD actions implicitly ready inside the routing table.
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 4 -- Generate the resource's components: controller, actions and views |
First generate the controller PostsController:
administrator@ubuntu:~/blog$ rails generate controller Posts
Running via Spring preloader in process 43022
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
invoke test_unit
create test/controllers/posts_controller_test.rb
invoke helper
create app/helpers/posts_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/posts.coffee
invoke scss
create app/assets/stylesheets/posts.scss
Then, the CRUD actions: new -- to bring a new page with form to create a new post create -- to create a new post based on the parameters from form show -- to display a post index -- to display a list of all posts edit -- to bring a updatable page to edit update -- to update a post based on the parameter from edit destroy -- to delete a post
app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
end
def create
render plain: params[:post].inspect
end
def show
end
def index
end
def edit
end
def update
end
def destroy
end
end
Finally the corresponding views:
app/views/posts/new.html.erb
<h1>New Post</h1>
<%= form_for :post, url: posts_path do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
This tells form's action going to url: posts_path which defaults to posts#create
def create
render plain: params[:post].inspect
end
This prints on browser the following:
<ActionController::Parameters {"title"=>"My First Post", "text"=>"This post to tell how to do ..."} permitted: false>
For sure, we need more than just display -- to save the post into a DB storage.
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 5 Create a model |
To create a new model, run this command:
administrator@ubuntu:~/blog$ rails generate model Post title:string text:text
Running via Spring preloader in process 44241
invoke active_record
create db/migrate/20170912222917_create_posts.rb
create app/models/post.rb
invoke test_unit
create test/models/post_test.rb
create test/fixtures/posts.yml
This is going to do: Create a model Post inside file app/models/post.rb
class Post < ApplicationRecord
end
Generate a database instruction file db/migrate/20170912222917_create_posts.rb
class CreatePosts < ActiveRecord::Migration[5.1]
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
to create a table posts with a title column of type string and a text column of type text, together with timestamps
Map the model Psot with the database table posts
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Database Setup for PostgreSQL |
Ruby on Rails recommends to create three databases: one for test, one for development and one for production environment
Check Install PostgreSQL if you do not have the PostgreSQL ready.
First, start the db server:
administrator@ubuntu:~$ sudo /etc/init.d/postgresql restart
Secondly, create a service account blog_admin:
administrator@ubuntu:~$ sudo -u postgres createuser blog_admin --no-createdb --no-superuser --no-createrole --pwprompt
Enter password for new role: <secret>
Enter it again: <secret>
Thirdly, create three databases: blog_test, blog_development and blog_production
administrator@ubuntu:~$ sudo -u postgres createdb blog_test --owner=blog_admin
administrator@ubuntu:~$ sudo -u postgres createdb blog_development --owner=blog_admin
administrator@ubuntu:~$ sudo -u postgres createdb blog_production --owner=blog_admin
Finally, you need to let Rails know about the user name and password for the databases. You do this in the file /config/database.yml within your Rails project directory.
When you finish, it should look something like :
# PostgreSQL
default: &default
adapter: postgresql
encoding: unicode
username: blog_admin
password: secret
host: localhost
development:
<<: *default
database: blog_development
production:
<<: *default
database: blog_production
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: blog_test
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Create Table for Model |
Now, you can use a Rails command to run the migration:
administrator@ubuntu:~/blog$ rails db:migrate
== 20170912222917 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.0216s
== 20170912222917 CreatePosts: migrated (0.0219s) =============================
administrator@ubuntu:~/blog$ rails db:migrate RAILS_ENV=test
== 20170912222917 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.0057s
== 20170912222917 CreatePosts: migrated (0.0060s) =============================
administrator@ubuntu:~/blog$ rails db:migrate RAILS_ENV=production
== 20170912222917 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.0056s
== 20170912222917 CreatePosts: migrated (0.0059s) =============================
You can verify the table by connecting to the database:
administrator@ubuntu:~/blog$ psql -h localhost -p 5432 -U blog_admin blog_development
Password for user blog_admin:
psql (9.6.5, server 9.3.19)
SSL connection (protocol: TLSv1.2, cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
blog_development=> \dt
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+------------
public | ar_internal_metadata | table | blog_admin
public | posts | table | blog_admin
public | schema_migrations | table | blog_admin
(3 rows)
blog_development=> \q
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Step 6 -- Save data into database |
Back to the controller app/controllers/posts_controller.rb, change the content of action create
class PostsController < ApplicationController
def new
end
def create
@post = Post.new(params[post_params])
@post.save
redirect_to @post
end
def show
@post = Post.find(params[:id])
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
This is going to do: Initialize the model Post with params from its respective attributes @post.save -- Save the model into it corresponding table posts redirect_to @post -- redirect the view to show require().permit() -- allow rights
Showing the post
app/views/posts/show.html.erb
<p>
<strong>Title:</strong>
<%= @post.title %>
</p>
<p>
<strong>Text:</strong>
<%= @post.text %>
</p>
|
|
|
|
|
|
|
Linux member offline |
|
posts: |
120 |
joined: |
01/24/2011 |
from: |
San Jose, CA |
|
|
|
|
|
Traffic flow |
Type into your browser: http://localhost:3000/blog/new
New Post
Title
[ ]
Text
[ ]
[Save Post]
Typing title and text and clicking on Save Post button should bring: http://localhost:3000/posts/1
Title: Post #2
Text: This is my second post.
You can also verify the data persistence in database:
administrator@ubuntu:~/blog$ psql -h localhost -p 5432 -U blog_admin blog_development
Password for user blog_admin:
psql (9.6.5, server 9.3.19)
SSL connection (protocol: TLSv1.2, cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
blog_development=> SELECT * FROM posts;
id | title | text | created_at | updated_at
----+----------+--------+--------------+-------------------
1 | Post#1 | This...| 2017-09-13 04:21:15.40803 | 2017-09-13 04:21:15.40803
2 | Post#2 | This...| 2017-09-13 04:25:12.514606 | 2017-09-13 04:25:12.514606
(2 rows)
|
|
|
|
|
|
|