焼きぶろぐ

思いついたことをだらだら書いてます

自由研究4日目 Rails

ようやくRailsの開発スタート、ということで
まずはドットインストールを見ながらサンプルブログアプリを開発しました。

以下メモです

Railsプロジェクト

新規作成手順

  • 1.プロジェクト作成
rails new myblog -TB --database=postgresql
sudo -u postgres psql
create role projectname with createdb login password 'password';
\q
  • 3.config\database.yml を編集 defaultのpoolの下
# 以下の3つを追加
username: projectname
password: password
# RailsサーバとPostgreSQLサーバが同じ場合
host: localhost
  • 4.bundle install
bundle install --path vendor/bundle

けっこう時間がかかる

rails db:setup
rails db:migrate
  • setup:開発DB(development)とテストDB(test)を作成してくれる。初回はshema.rbが不足していると怒られる
  • migrate:shema.rb作成

ちなみにmigrateのリセット(データ初期化)は

rails db:migrate:reset

WEBサーバ

起動

rails server -b 192.168.33.10 -d

切断(プロセスidを検索し、指定して殺す)

cat tmp/pids/server.pid
kill -9 9113

DB参照

PostgreSQLに接続します

rails db

モデル

モデル作成

名称は大文字始まり・英語の単数形でモデル名を指定する
モデルのファイルはapp/models/モデル名.rbに自動で作成される。
migrateするとDBに複数形名のテーブルが自動で作成される

rails g model Post title:stging body:text
rails db:migrate

既存のモデルと紐づけるためにはreferencesを付ける
下記例ではPost-Commentで1-nの関係。Commentテーブルにpost_id列が自動で付与される

rails g model Comment body:string post:references

モデル同士の紐づけ

モデルファイルに紐づけの情報を設定する

1-nの1側(post)

has_many :comments

これによって@post.commentsの形で取得できるようになる
削除時にn側のデータも削除する場合は下記のように書く

has_many :comments, dependent: :destroy

n側(モデル生成時に指定していたら勝手に表現される)

belongs_to :post

Validation処理

項目のチェック処理定義
必須はpresence

  validates :title, presence: true, length: { minimum: 3, message: 'Too short to post' }
  validates :body, presence: true

初期データ設定

db/seeds.rb を編集して設定できる
モデル名.create形式で書く

Post.create(要素1:'要素1内容',要素2:'要素2内容')

実行する場合は

rails db:seed

コントローラ

コントローラ作成

コントローラは大文字始まり・複数形で作成する

rails g controller Posts

これを実行すると、app/controllers/posts_controller.rbが自動生成される

ルーティング

どのメソッドをどのURLに設定するか、の設定

config/routes.rb を編集する

resources :posts

1-nのモデルを扱うときは下記のようにする

resources :posts do
    resources :comments

これを設定すると、自動でルートを生成してくれる

rails routes

また、一部のルートしか使用しない(create,destroyのみなど)場合は下記のように記述する

resources :comments, only: [:create, :destroy]

ルートパスをpostのindexに指定したい場合

root 'posts#index'

コントローラ編集

各メソッド(アクションメソッド)を定義します

index(一覧)例

def index
  @posts = Post.all.order(created_at: 'desc')
end

show(照会)例

:idはルーティングで設定されているため

def show
    @post = Post.find(params[:id])
end

create(作成)例

def create
  # 受け取ったものをそのまま表示して確認するとき
  # render plain: params[:post].inspect
  # save
  @post = Post.new(params.require(:post).permit(:title, :body)[:post])
  @post = Post.new(post_params)
  if @post.save
    #redirect
    redirect_to posts_path
  else
    render plain: @post.errors.inspect
  end
end

destroy(削除)例

def destroy
  @post = Post.find(params[:id])
  @post.destroy
  redirect_to posts_path
end

メソッド化

def create
  @post = Post.new(post_params)
end
 private
  def post_params
    params.require(:post).permit(:title, :body)
  end

ビュー

app/views/posts/にメソッド名.html.erbというファイル名で作成する

<% %>

で囲ったところがプログラム部分、ほかは素のhtml

<h2>My Posts</h2>
<ul>
<% @posts.each do |post| %>
    <li><%= post.title %></li>
<% end %>
</ul>

アプリ全体の共通ビュー

layouts/application.html.erbで設定されてる

ちなみにcssはapp/assets/stylesheets/application.css

ヘルパー

たくさんのヘルパーが用意されている

リンクヘルパー

aタグ

<%= 見出し, パス(渡す値) %>
<!-- 新規へのリンク -->
<%= link_to 'Add New', new_post_path, class: 'header-menu' %>
<!-- 編集へのリンク -->
<%= link_to '[Edit]', edit_post_path(post),class: 'command' %>
<!-- 削除へ -->
<%= link_to '[x]', post_path(post), method: :delete, class: 'command' %>

イメージヘルパー

imgタグ

<%= image_tag 'logo.png' ,class: 'logo' %>

タグを重ねる場合

aの中にimgタグ

<%= link_to image_tag('logo.png' ,class: 'logo'), root_path %>

フォームヘルパー

<%= form_for :@post do |f| %>
...
<% end %>

インプット系

<!-- テキストボックス -->
<%= f.text_field :title, placeholder: 'enter title' %>
<!-- テキストエリア -->
<%= f.text_area :body, placeholder: 'enter body text' %>
<!-- ボタン -->
<%= f.submit %>

部品化

views/postsの中に_からはじめた名前のファイルを生成すると、各ビューから呼び出せる部品となる

form_forのパラメタはroutesでresourceを設定しているのでよしなにやってくれる、らしい(よくわかっていない)

viewから呼び出すときは_抜きの部品名を指定する

<%=  render 'form' %>

クリック時に警告を出したい場合は

data: { confirm: 'Sure?' }

エラーメッセージを出したい場合

エラーの数だけ繰り返しspan

<% if @post.errors.messages[:title].any? %>
<span class="error"><%= @post.errors.messages[:title][0] %></span>
<% end %>