mkdir rails_sample_app
cd rails_sample_app
- Make Gemfile on APPNAME directory:
bundle init
- Remove
#
forgem "rails"
on Gemfile:
# gem 'rails'
↓
gem 'rails'
- Install Rails:
bundle install --path=vendor/bundle
- Set build-flags for Installing
gem 'mysql2'
:
bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
- Create a new Rails app using MySQL:
bundle exec rails new . --database=mysql
- Add to index for all changed files on a repository:
git add .
"repository" is a space which manages states of project data.
- Commit with an massage:
git commit -m "first commit"
- Access GitHub.com and create an repository.
USERNAME/rails_sample_app
- Connect a local repository and a remote repository:
git remote add origin https://github.com/USERNAME/rails_sample_app.git
- "local" is managed by your computer
- "remote" is managed by an Web service like GitHub.
- Push a local's commits to a remote:
git push -u origin master
- Checkout
develop
branch frommaster
:
git checkout -b develop
- Push
develop
toorigin develop
:
git push origin develop
Local | Remote | |
---|---|---|
repository | rails_sample_app | github.com/*/rails_sample_app |
default branch | master | origin master |
current branch | develop | origin develop |
- Create new databases:
bundle exec rails db:create
- Launch local server by puma:
bundle exec rails server
-
Go to
http://localhost:3000
to check your app. -
Yay! You're on Rails!
-
git add & commit
- Design Tweet model's table
columnns | type | memo |
---|---|---|
id | integer | auto created by rails |
body | string | max-length: 120, null: false |
created_at | timestamp | auto created by rails |
updated_at | timestamp | auto created by rails |
- Generate Tweet model and migration file:
bundle exec rails generate model Tweet body:string
- Migrate Tweet table to database:
bundle exec rails db:migrate
git add & commit
- Design
tweets_controller
Action | Behavior |
---|---|
index | get all tweets |
show | get a tweet |
new | create a new tweet |
create | post a new tweet to model |
edit | get a tweet for edit |
update | post a edited tweet to model |
destroy | destroy a tweet |
- Generate
tweets_controller
:
bundle exec rails g controller tweets
git add & commit
- Open
app/controllers/tweets_controller.rb
:
class TweetsController < ApplicationController
end
- Define
index
method:
class TweetsController < ApplicationController
# --- start ---
def index
@tweets = Tweet.all
end
# --- end ---
end
git add & commit
- Define
show
method:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
# --- start ---
def show
@tweet = Tweet.find_by(id: params[:id])
end
# --- end ---
end
git add & commit
- Define
new
method:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
@tweet = Tweet.find_by(id: params[:id])
end
# --- start ---
def new
@tweet = Tweet.new
end
# --- end ---
end
git add & commit
- Define Strong Parameters on private:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
@tweet = Tweet.find_by(id: params[:id])
end
def new
@tweet = Tweet.new
end
# --- start ---
private
def tweet_params
params.require(:tweet).permit(:body)
end
# --- end ---
end
- Define
create
method:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
@tweet = Tweet.find_by(id: params[:id])
end
def new
@tweet = Tweet.new
end
# --- start ---
def create
@tweet = Tweet.new(tweet_params)
if @tweet.save
redirect_to tweets_path
else
render :new
end
end
# --- end ---
private
def tweet_params
params.require(:tweet).permit(:body)
end
end
git add & commit
- Open
app/config/routes.rb
:
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
- Set routing for tweets_controller:
# How to write routing
root 'controller#action'
get '/path', to: 'controller#action'
post '/path', to: 'controller#action'
resources :controller
# etc ...
- resources:
resources :tweets
↑ Same routing ↓
get '/tweets', to: 'tweets#index'
get '/tweets/:id', to: 'tweets#show'
get '/tweets/new', to: 'tweets#new'
post '/tweets', to: 'tweets#create'
get '/tweets/:id/edit', to: 'tweets#edit'
patch '/tweets/:id', to: 'tweets#update'
delete '/tweets/:id', to: 'tweets#destroy'
- this time:
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
resources :tweets
end
- Check routing:
bundle exec rails routes
git add & commit
- create new files in
app/views/tweets
app/
assets/
channels/
controllers/
helpers/
jobs/
mailers/
models/
* views/
layouts/
* tweets/
index.html.erb
show.html.erb
new.html.erb
erb extension: Embed Ruby for HTML
git add & commit
- Edit
index.html.erb
:
<h1>Tweets#index</h1>
<%= link_to "New Tweet", new_tweet_path %>
<% @tweets.each do |tweet| %>
<p><%= tweet.body %></p>
<%= link_to 'Show', tweet %>
<% end %>
git add & commit
- Edit
show.html.erb
<h1>Tweets#show</h1>
<h3><%= @tweet.body %></h3>
<p><%= @tweet.updated_at %><p>
<%= link_to "Back", :back %>
git add & commit
- Edit
new.html.erb
<h1>Tweets#new</h1>
<%= form_with(model: @tweet, local: true) do |form| %>
<div>
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
<%= link_to "Back", :back %>
git add & commit
- Remind: Design of
tweets_controller
Action | Behavior |
---|---|
index | get all tweets |
show | get a tweet |
new | create a new tweet |
create | post a new tweet to model |
edit | get a tweet for edit |
update | post a edited tweet to model |
destroy | destroy a tweet |
- Define
edit
,update
anddestroy
method:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
@tweet = Tweet.find_by(id: params[:id])
end
def new
@tweet = Tweet.new
end
def create
@tweet = Tweet.new(tweet_params)
if @tweet.save
redirect_to tweets_path
else
render :new
end
end
# ------ start ------
def edit
@tweet = Tweet.find_by(id: params[:id])
end
def update
@tweet = Tweet.find_by(id: params[:id])
if @tweet.update(tweet_params)
redirect_to tweets_path
else
render :edit
end
end
def destroy
@tweet = Tweet.find_by(id: params[:id])
@tweet.destroy
redirect_to tweets_path
end
# ------ end ------
private
def tweet_params
params.require(:tweet).permit(:body)
end
end
git add & commit
DRY is one of Ruby on Rails' philosophies.
It means you must reduce same programs as much as possible.
Now, We rewrite tweets_controller
to follow DRY.
- Define
set_tweet
method underprivate
:
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def show
@tweet = Tweet.find_by(id: params[:id])
end
def new
@tweet = Tweet.new
end
def create
@tweet = Tweet.new(tweet_params)
if @tweet.save
redirect_to tweets_path
else
render :new
end
end
def edit
@tweet = Tweet.find_by(id: params[:id])
end
def update
@tweet = Tweet.find_by(id: params[:id])
if @tweet.update(tweet_params)
redirect_to tweets_path
else
render :edit
end
end
def destroy
@tweet = Tweet.find_by(id: params[:id])
@tweet.destroy
redirect_to tweets_path
end
private
def tweet_params
params.require(:tweet).permit(:body)
end
# ------ start ------
def set_tweet
@tweet = Tweet.find_by(id: params[:id])
end
# ------ end ------
end
- Set
before_action
to head oftweets_controller
and remove same variables in some methods:
class TweetsController < ApplicationController
# ------ start ------
before_action :set_tweet, only: [:show, :edit, :update, :destroy]
# ------ end ------
def index
@tweets = Tweet.all
end
def show
# @tweet = Tweet.find_by(id: params[:id]) REMOVE
end
def new
@tweet = Tweet.new
end
def create
@tweet = Tweet.new(tweet_params)
if @tweet.save
redirect_to tweets_path
else
render :new
end
end
def edit
# @tweet = Tweet.find_by(id: params[:id]) REMOVE
end
def update
# @tweet = Tweet.find_by(id: params[:id]) REMOVE
if @tweet.update(tweet_params)
redirect_to tweets_path
else
render :edit
end
end
def destroy
# @tweet = Tweet.find_by(id: params[:id]) REMOVE
@tweet.destroy
redirect_to tweets_path
end
private
def tweet_params
params.require(:tweet).permit(:body)
end
def set_tweet
@tweet = Tweet.find_by(id: params[:id])
end
end
- Create
edit.html.erb
and_form.html.erb
:
app/
assets/
channels/
controllers/
helpers/
jobs/
mailers/
models/
* views/
layouts/
* tweets/
index.html.erb
show.html.erb
new.html.erb
* edit.html.erb
* _form.html.erb
_form.html.erb
will use new.html.erb
and edit.html.erb
as partial.
git add & commit
Partial is a shareble program for some view files.
- Edit
_form.html.erb
:
<!-- rename @tweet to tweet -->
<%= form_with(model: tweet, local: true) do |form| %>
<div>
<h3><%= form.label :body %></h3>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
git add & commit
- Add render partial to
new.html.erb
and remove previous program :
<h1>Create a new tweet</h1>
<!-- ADD -->
<%= render "form", tweet: @tweet %>
<!-- ADD -->
<%= link_to "Back", tweets_path %>
<!-- REMOVE -->
<%= form_with(model: @tweet, local: true) do |form| %>
<div>
<h3><%= form.label :body %></h3>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
<!-- REMOVE -->
- Also, add render partial to
edit.html.erb
:
<h1>Edit a tweet</h1>
<%= render "form", tweet: @tweet %>
<%= link_to "Back", tweets_path %>
git add & commit
- Add Edit and Delete button to
show.html.erb
:
<h1>Show a tweet</h1>
<h3><%= @tweet.body %></h3>
<p><%= @tweet.updated_at %><p>
<%= link_to "Back", tweets_path %>
<!-- ADD -->
<%= link_to "Edit", edit_tweet_path(@tweet) %>
<%= link_to 'Destroy', @tweet, method: :delete, data: { confirm: 'Are you sure?' } %>
<!-- ADD -->