sexta-feira, 24 de março de 2017
sábado, 18 de março de 2017
RAILS Creating Static Pages in a Rails App
1. Introduction
This post gathers information about how to create Static Pages in RAILS.2. Step by Step
2.1. Creating controller 'staticpages' for static pages
$ rails generate controller staticpages --skip-assetsRunning via Spring preloader in process 3573
create app/controllers/staticpages_controller.rb
invoke erb
create app/views/staticpages
invoke test_unit
create test/controllers/staticpages_controller_test.rb
invoke helper
create app/helpers/staticpages_helper.rb
invoke test_unit
2.2. Edit Controller 'staticpages' to implement actions
$ vim app/controllers/staticpages_controller.rb
class StaticpagesController < ApplicationController
def show
if valid_page?
render template: "staticpages/#{params[:page]}"
else
render file: "public/404.html", status: :not_found
end
end
private
def valid_page?
File.exist?(Pathname.new(Rails.root + "app/views/staticpages/#{params[:page]}.html.erb"))
end
end
def show
if valid_page?
render template: "staticpages/#{params[:page]}"
else
render file: "public/404.html", status: :not_found
end
end
private
def valid_page?
File.exist?(Pathname.new(Rails.root + "app/views/staticpages/#{params[:page]}.html.erb"))
end
end
2.3. Edit Routes for 'staticpages' and redirect root to staticpages/home
$ vim config/routes.rb
Rails.application.routes.draw do
:
get "/staticpages/:page" => "staticpages#show"
root 'staticpages#home'
root 'staticpages#home'
:
2.4. Edit some StaticPages: home, sitemap, userdoc, about
$ vim app/views/staticpages/home.html.erb
<h1>Static Page #Home</h1>
Find me in app/views/staticpages/home.html.erb
$ vim app/views/staticpages/sitemap.html.erb
<h1>Static Page #Sitemap</h1>
Find me in app/views/staticpages/sitemap.html.erb
$ vim app/views/staticpages/userdoc.html.erb
<h1>Static Page #Userdoc</h1>
Find me in app/views/staticpages/userdoc.html.erb
$ vim app/views/staticpages/about.html.erb
<h1>Static Page #About</h1>
Find me in app/views/staticpages/about.html.erb
2.5. Test StaticPages
3. References
RAILS Using console
1. Introduction
This post shows how to use RAILS Console.2. Step-by-Step
2.1. Pre-Conditions
You should have a model post title:string body:text and another model comment post: reference body: text. References #1 has a step-by-step of creating objects2.2. Executing some RAILS console commands
- Run Console
$ rails console
Running via Spring preloader in process 2669
Loading development environment (Rails 5.0.2)
- Get first record from model 'Post'
irb(main):001:0> Post.first
Post Load (3.6ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Post id: 1, title: "1", body: "first", created_at: "2017-03-18 15:15:30", updated_at: "2017-03-18 15:16:05">
- Get all records from model 'Post'
irb(main):004:0> Post.all
Post Load (0.6ms) SELECT "posts".* FROM "posts"
=> #<ActiveRecord::Relation [#<Post id: 1, title: "1", body: "first", created_at: "2017-03-18 15:15:30", updated_at: "2017-03-18 15:16:05">]>
- Get records using criteria of filter created_at - result using JSON
irb(main):096:0* Post.where(created_at: Date.yesterday..Date.tomorrow)
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE ("posts"."created_at" BETWEEN $1 AND $2) [["created_at", Fri, 17 Mar 2017], ["created_at", Sun, 19 Mar 2017]]
=> #<ActiveRecord::Relation [#<Post id: 1, title: "1", body: "first", created_at: "2017-03-18 15:15:30", updated_at: "2017-03-18 15:16:05">]>
- Get records using criteria of filter created_at - result using SQL
=> "SELECT \"posts\".* FROM \"posts\" WHERE (\"posts\".\"created_at\" BETWEEN '2017-03-17' AND '2017-03-19')"
- Create a record of Post
irb(main):124:0* Post.create! title: 'Hello World', body: 'One World', created_at: '2017-03-15 15:45', updated_at: '2017-03-15 15:45'
(0.1ms) BEGIN
SQL (47.5ms) INSERT INTO "posts" ("title", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["title", "Hello World"], ["body", "One World"], ["created_at", 2017-03-15 15:45:00 UTC], ["updated_at", 2017-03-15 15:45:00 UTC]]
(22.7ms) COMMIT
=> #<Post id: 2, title: "Hello World", body: "One World", created_at: "2017-03-15 15:45:00", updated_at: "2017-03-15 15:45:00">
- Create a record of 'Comments' from first 'Post'
Post Load (0.4ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = $1 [["post_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy []>
- Add a record of 'Comments' into first 'Post'
irb(main):002:0> Post.first.comments.create! body: 'Say something funny'
Post Load (0.4ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.1ms) BEGIN
SQL (1.0ms) INSERT INTO "comments" ("post_id", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["post_id", 1], ["body", "Say something funny"], ["created_at", 2017-03-18 19:19:38 UTC], ["updated_at", 2017-03-18 19:19:38 UTC]]
(15.0ms) COMMIT
=> #<Comment id: 1, post_id: 1, body: "Say something funny", created_at: "2017-03-18 19:19:38", updated_at: "2017-03-18 19:19:38">
- Get records of 'Comments' from first 'Post' again - after 'Say something funny' created
irb(main):003:0> Post.first.comments
Post Load (0.3ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = $1 [["post_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Comment id: 1, post_id: 1, body: "Say something funny", created_at: "2017-03-18 19:19:38", updated_at: "2017-03-18 19:19:38">]>
irb(main):004:0>
3. References
RAILS Using Scaffold to create CRUD application on PostgreSQL
1. Introduction
This post shows how to create a simple application using scaffolding generator connectiong to PostgreSQL.2. Step-by-Step
2.1. Create application named 'weblog' using 'PostgreSQL' database
$ pwd/home/rails-home
$ rails new weblog -d postgresql
$ cd weblog
$ pwd
/home/rails-home/weblog
2.2. Generate scaffold CRUD for 'post' entity with attributes title:string and body:string
a. Generate scaffold
$ rails generate scaffold post title:string body:textRunning via Spring preloader in process 2854
invoke active_record
create db/migrate/20170318144830_create_posts.rb
create app/models/post.rb
: :
invoke resource_route
route resources :posts
invoke scaffold_controller
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
create app/views/posts/index.html.erb
create app/views/posts/edit.html.erb
create app/views/posts/show.html.erb
create app/views/posts/new.html.erb
create app/views/posts/_form.html.erb
: :
invoke jbuilder
create app/views/posts/index.json.jbuilder
create app/views/posts/show.json.jbuilder
create app/views/posts/_post.json.jbuilder
: :
b. Checking what scaffold has done:
(i) migration script
$ cat db/migrate/*_create_posts.rbclass CreatePosts < ActiveRecord::Migration[5.0]
def change
create_table :posts do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
(ii) model for application
$ cat app/models/post.rbclass Post < ApplicationRecord
end
(iii) controller with actions new, create, ..., destroy
$ cat app/controllers/posts_controller.rbclass PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
:
def index
:
end
:
def show
:
end
:
def new
:
end
:
def edit
:
end
:
def create
:
end
:
def update
:
end
:
def destroy
:
end
:
private
def set_post
:
end
:
def post_params
:
end
:
end
(iv) views
$ ls -la app/views/poststotal 36
drwxr-xr-x. 2 root root 4096 Mar 18 11:48 .
drwxr-xr-x. 4 root root 32 Mar 18 11:48 ..
-rw-r--r--. 1 root root 123 Mar 18 11:48 edit.html.erb
-rw-r--r--. 1 root root 579 Mar 18 11:48 _form.html.erb
-rw-r--r--. 1 root root 591 Mar 18 11:48 index.html.erb
-rw-r--r--. 1 root root 53 Mar 18 11:48 index.json.jbuilder
-rw-r--r--. 1 root root 88 Mar 18 11:48 new.html.erb
-rw-r--r--. 1 root root 104 Mar 18 11:48 _post.json.jbuilder
-rw-r--r--. 1 root root 227 Mar 18 11:48 show.html.erb
-rw-r--r--. 1 root root 40 Mar 18 11:48 show.json.jbuilder
c. Start RAILS server and observe what scaffold does for us
i) Configure RAILS on to listen for all interfaces
$ vim ./config/boot.rb:
super.merge(Host: '0.0.0.0', Port: 3000)
:
ii) Create databases DEV and PROD using
$ rake db:createiii) Create database tables using migrate
$ rails db:migrateiv) Run rails server
$ rails serverv) Check results
- http://localhost:3000 - See Yay! You're on Rails!
- http://localhost:3000/posts - Simple CRUD application for Posts, you can do: new, show, edit, destroy
- http://localhost:3000/posts.json - JSON object representing all posts: [{"id":1,"title":"1","body":"first","created_at":"2017-03-18T15:15:30.015Z","updated_at":"2017-03-18T15:16:05.960Z","url":"http://localhost:3000/posts/1.json"}]
2.3. Adding some validation
- Edit model and add validation rule
$ vim app/models/post.rb
class Post < ApplicationRecord
validates_presence_of :title
end
- Try to create a post without title and observe error validation: 1 error prohibited this post from being saved: Title can't be blank
2.3. Creating Comment model reference Post (master detail)
a. Create resource comment referencing post
$ rails generate resource comment post:references body:text
Running via Spring preloader in process 3025
invoke active_record
create db/migrate/20170318185201_create_comments.rb
create app/models/comment.rb
invoke test_unit
create test/models/comment_test.rb
create test/fixtures/comments.yml
invoke controller
create app/controllers/comments_controller.rb
invoke erb
create app/views/comments
invoke test_unit
create test/controllers/comments_controller_test.rb
invoke helper
create app/helpers/comments_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/comments.coffee
invoke scss
create app/assets/stylesheets/comments.scss
invoke resource_route
route resources :comments
== 20170318185201 CreateComments: migrating ===================================
-- create_table(:comments)
-> 0.1987s
== 20170318185201 CreateComments: migrated (0.1988s) ==========================
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
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
Running via Spring preloader in process 3025
invoke active_record
create db/migrate/20170318185201_create_comments.rb
create app/models/comment.rb
invoke test_unit
create test/models/comment_test.rb
create test/fixtures/comments.yml
invoke controller
create app/controllers/comments_controller.rb
invoke erb
create app/views/comments
invoke test_unit
create test/controllers/comments_controller_test.rb
invoke helper
create app/helpers/comments_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/comments.coffee
invoke scss
create app/assets/stylesheets/comments.scss
invoke resource_route
route resources :comments
b. Run migrate to create database table for 'comment'
$ rails db:migrate== 20170318185201 CreateComments: migrating ===================================
-- create_table(:comments)
-> 0.1987s
== 20170318185201 CreateComments: migrated (0.1988s) ==========================
c. Configure nesting of routes on post controller to comment'
$ vim config/routes.rb
Rails.application.routes.draw do
resources :posts do
resources :comments
end
end
d. Check routes created
$ rails routes
Prefix Verb URI Pattern Controller#Actionpost_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
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
e. Check model 'comment' created
$ cat app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :post
end
f. Adjust 'post' model to has many of 'comment' models
$ vim app/models/post.rb
class Post < ApplicationRecord
has_many :comments
validates_presence_of :title
end
2.4. Edit view of 'post' to show related 'comments'
a. Edit view 'show' of 'post' - add code to show related comments
$ vim app/views/posts/show.html.erb
<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>
<br><br>
<h2>Comments</h2>
<div id="comments">
<%# Expands to render partial: 'comments/comment', collection: @post.comments %>
<%= render @post.comments %>
</div>
<%= render 'comments/new', post: @post %>
</div>
b. Edit view templates '_form' and '_new' of 'Comment'
$ vim app/views/comments/_new.html.erb<%= form_for([ @post, Comment.new ], remote: true) do |form| %>
Your comment:<br>
<%= form.text_area :body, size: '50x20' %><br>
<%= form.submit %>
<% end %>
$ vim app/views/comments/_comment.html.erb
<p><%= comment.body %> -- <%= comment.created_at.to_s(:log) %><p>
c. Implement 'comment' controller actions
$ vim app/controllers/comments_controller.rbclass CommentsController < ApplicationController
before_action :set_post
def create
@post.comments.create! comments_params
redirect_to @post
end
private
def set_post
@post = Post.find(params[:post_id])
end
def comments_params
params.required(:comment).permit(:body)
end
end
3. References
- http://rubyonrails.org/
- https://www.youtube.com/watch?v=OaDhY_y8WTo
- http://josemarfuregattideabreusilva.blogspot.com.br/2017/03/creating-simple-ruby-on-rails.html
sexta-feira, 17 de março de 2017
RAILS Creating a simple Ruby on RAILS application with PostgreSQL database
1. Introduction
This post gathers information about creating a Ruby on RAILS application with PostgreSQL2. Step-by-step
2.1. Create a Ruby on RAILS with PostgreSQL database
$ pwd/home/rails-home
$ rails new myrailsapppostgres -d postgresql
2.2. Grant PostgreSQL database permission for administration user 'root' used on RAILS
$ psqlpostgres=# CREATE USER root WITH PASSWORD 'root';
postgres=# GRANT postgres TO root;
postgres=# ALTER USER root CREATEDB;
postgres=# \q
2.3. Create RAILS database
$ pwd/home/rails-home/myrailsapppostgres
$ rake db:create
Created database 'myrailsapppostgres_development'
Created database 'myrailsapppostgres_test'
2.4. Configure RAILS to listen for any 0.0.0.0 IP adddress on Port 3000 (default is 127.0.0.1:3000)
$ pwd/home/rails-home/myrailsapppostgres
$ vim ./config/boot.rb
:
require 'rails/commands/server'
module Rails
class Server
def default_options
super.merge(Host: '0.0.0.0', Port: 3000)
end
end
end
:
2.5. Create Welcome page
$ pwd/home/rails-home/myrailsapppostgres
$ rails generate controller Welcome index
$ vim app/views/welcome/index.html.erb
<h1>Welcome#index</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
$ vim config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
root 'welcome#index'
end
2.6. Exploring RAILS files and folders
- 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, 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.
- 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.
- Gemfile :
- Gemfile.lock : These files allow you to specify what gem dependencies are needed for your Rails application. These files are used by the Bundler gem. For more information about Bundler, see the Bundler website.
- lib/: Extended modules for your application.
- 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.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.
- 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.
2.7. Creating a simple RAILS application
a) create a resource 'articles' and check routes
$ pwd/root/rails-home/myrailsapppostgres
$ vim config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :articles
root 'welcome#index'
end
b) check all RESTfull actions
$ rails routesPrefix Verb URI Pattern Controller#Action
welcome_index GET /welcome/index(.:format) welcome#index
root GET / welcome#index
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
c) Create a model for article
- Generate RAILS model for Article
$ rails generate model Article title:string text:text
Running via Spring preloader in process 3657
invoke active_record
create db/migrate/20170317185317_create_articles.rb
create app/models/article.rb
invoke test_unit
create test/models/article_test.rb
create test/fixtures/articles.yml
- Checking migrate scripts automatically generated by RAILS
$ cat db/migrate/*_create_articles.rb
class CreateArticles < ActiveRecord::Migration[5.0]
def change
create_table :articles do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
$ cat app/models/article.rb
class Article < ApplicationRecord
validates :title, presence: true, length: { minimum: 3 }
end
- Run migrate scripts on environment (DEVELOPMENT)
$ rails db:migrate
== 20170317185317 CreateArticles: migrating ===================================
-- create_table(:articles)
-> 0.0092s
== 20170317185317 CreateArticles: migrated (0.0093s) ==========================
- Checking on PostgreSQL databases databases created by scripts
$ psql -h 127.0.0.1 -d myrailsapppostgres_development -U root -W
myrailsapppostgres_development=> \l
List of databases
Name | Owner
-------------------------------+----------
myrailsapppostgres_development | root ...
myrailsapppostgres_test | root ...
: :
- Checking on PostgreSQL databases tables created by scripts
myrailsapppostgres_development=> \d
List of relations
Schema | Name | Type | Owner
--------+----------------------+----------+-------
public | ar_internal_metadata | table | root
public | articles | table | root
public | articles_id_seq | sequence | root
public | schema_migrations | table | root
(4 rows)
- Checking on PostgreSQL databases table description created by scripts
myrailsapppostgres_development=> \d articles
Table "public.articles"
Column | Type | Modifiers
------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('articles_id_seq'::regclass)
title | character varying |
text | text |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
Indexes:
"articles_pkey" PRIMARY KEY, btree (id)
d) Create controller for article and implement actions from CRUD capabilities
$ rails generate controller Articles$ vim app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
end
$ vim app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def new # new action
@article = Article.new
end
def create # create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render 'new'
end
end
def show # show
@article = Article.find(params[:id])
end
def index # list
@articles = Article.all
end
def edit # edit
@article = Article.find(params[:id])
end
def update # 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
def article_params
params.require(:article).permit(:title, :text)
end
end
e) Create views for article and implement pages from CRUD capabilities: welcome index, new-create, show, list, edit and destroy
- welcome#index: view for application Welcome
$ vim app/views/welcome/index.html.erb
<h1>Welcome#index</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
<%= link_to 'Articles', controller: 'articles' %>
- new: view for new record
$ vim app/views/articles/new.html.erb
<h1>New Article</h1>
<%= form_for :article, url: articles_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 %>
- show: view for show record
$ vim app/views/articles/show.html.erb
<h1>Show Article</h1>
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<%= link_to 'Back', articles_path %>
- list: view for listing all records
$ vim app/views/articles/index.html.erb
<h1>Listing articles</h1>
<table>
<tr>
<th>Title</th>
<th>Text</th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
- edit: view for edit record
$ vim app/views/articles/edit.html.erb
<h1>Editing article</h1>
<%= form_for :article, url: article_path(@article), method: :patch do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<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 %>
<%= link_to 'Back', articles_path %>
f) Testing simple application CRUD
- http://localhost:3000/ - should return your welcome index
- http://localhost:3000/articles - should return a list of articles on database and you can show, edit or destroy
- http://localhost:3000/articles/new - should return a empty article form
2.8. Adding some validation to simple RAILS application
- Required fields and minimum limit of fields
$ vim app/models/article.rb
class Article < ApplicationRecord
validates :title, presence: true, length: { minimum: 3 }
end
- Capture new errors exceptions and show on top of page
$ vim app/views/articles/new.html.erb
:
<%= form_for :article, url: articles_path do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
:
2.9. Using form to clean up duplications on view
a. Backup 'new' and 'edit' form
$ cp app/views/articles/new.html.erb app/views/articles/new.html.erb.without_form$ cp app/views/articles/edit.html.erb app/views/articles/edit.html.erb.without_form
b. Create template '_form' to be included by 'new' and 'edit'
$ vim app/views/articles/_form.html.erb<%= form_for @article do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<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 %>
c. Change 'new' to include '_form'
$ vim app/views/articles/new.html.erb<h1>New Article</h1>
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
d. Change 'edit' to include '_form'
$ vim app/views/articles/edit.html.erb<h1>Editing article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
2.10. Adding second model detail of first master model
a. Create model comment detail of master article: one article has many comments
$ rails generate model Comment commenter:string body:text article:referencesRunning via Spring preloader in process 8667
invoke active_record
create db/migrate/20170318010912_create_comments.rb
create app/models/comment.rb
invoke test_unit
create test/models/comment_test.rb
create test/fixtures/comments.yml
b. Checking migrate scripts automatically generated by RAILS
$ cat db/migrate/*_create_comments.rb$ cat app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :article
end
$ cat test/models/comment_test.rb
:
$ cat test/fixtures/comments.yml
:
c. Run migrate scripts on environment (DEVELOPMENT)
$ rails db:migrate== 20170318010912 CreateComments: migrating ===================================
-- create_table(:comments)
-> 0.1321s
== 20170318010912 CreateComments: migrated (0.1323s) ==========================
d. Associating models
$ vim app/models/article.rbclass Article < ApplicationRecord
has_many :comments
validates :title, presence: true, length: { minimum: 5 }
end
e. Adding routing for new model comments
$ vim config/routes.rbRails.application.routes.draw do
get 'welcome/index'
resources :articles do
resources :comments
end
root 'welcome#index'
end
f. Generating a controller for detail new model Comment
$ rails generate controller Comments$ cat app/controllers/comments_controller.rb # will be changed soon
class CommentsController < ApplicationController
end
$ ls -lad app/views/comments/
$ ls -la test/controllers/comments_controller_test.rb
$ cat app/helpers/comments_helper.rb
module CommentsHelper
end
$ cat app/assets/javascripts/comments.coffee
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
$ cat app/assets/stylesheets/comments.scss
// Place all the styles related to the Comments controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
g. Edit article view 'show' to let make a new details records of comments
$ vim app/views/articles/show.html.erb<h1>Show Article</h1>
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<% @article.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
h. Edit comments controller 'show' to implement 'create' and 'destroy'
$ vim app/controllers/comments_controller.rbclass CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
def destroy
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
$ vim app/views/articles/show.html.erb
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<% @article.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
i. Partial Comments to clean up 'show' with a template
$ cp app/views/articles/show.html.erb app/views/articles/show.html.erb.without_form$ vim app/views/comments/_comment.html.erb
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<p>
<%= link_to 'Destroy Comment', [comment.article, comment],
method: :delete,
data: { confirm: 'Are you sure?' } %>
</p>
j. Partial Form _form coments._form
$ vim app/views/comments/_form.html.erb<%= form_for([@article, @article.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br>
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
k. Partial Form _form article.show
$ vim app/views/articles/show.html.erb<h1>Show Article</h1>
<p>
<strong>Title:</strong>
<%= @article.title %>
</p>
<p>
<strong>Text:</strong>
<%= @article.text %>
</p>
<h2>Comments</h2>
<%= render @article.comments %>
<h2>Add a comment:</h2>
<%= render 'comments/form' %>
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
l. Adding method 'create' and 'destroy' to controller Comments
$ vim app/controllers/comments_controller.rbclass CommentsController < ApplicationController
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
def destroy
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
m. Deleting associated Objects
$ vim app/models/article.rb
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
validates :title, presence: true, length: { minimum: 3 }
end
3. References
- https://hostpresto.com/community/tutorials/how-to-install-ruby-on-rails-on-centos-7/
- http://guides.rubyonrails.org/getting_started.html
Assinar:
Postagens (Atom)