環境構築
やりたいこと
- railsなどのgemはプロジェクトごとにバージョン管理したい。
- githubを基本利用する
- mysqlを利用したい
前提
- bundleはグローバルにインストールされてる
構築
mkdir project
cd project
bundle init
vim Gemfile
〜〜 gem 'rails'のコメントアウトを外す〜〜
bundle install --path=vendor/bundle
bundle exec rails new . -d mysql
〜〜 Gemfileは上書きしてOK〜〜
git init
vim gitignore
〜〜 https://www.gitignore.io/ を参照〜〜
git remote add origin hogehoge.git
rails new
のオプションに関しては、
bundle exec rails new -h
で参照してください。
ここではmysqlを指定しますが、デフォルトだとsqlite3になります。
知っておくべき基礎
routes.rb
root users#index
=> 初期画面
resources :posts
=> シンボリック、複数形
resources :posts do
resources :comments
end
=> postの内側にネストされたリソースとしてcommentsが作成される。
rails generate
bundle exec rails generate controller Users
=> 大文字、複数形
bundle exec rails generate model Post title:string
=> 大文字、単数形
=> DBは複数形となる。
bundle exec rails generate model Comment commenter:string body:text article:references
=> articleモデルと紐づけられる。
=> belongs_to :article
=> article_id
というカラムを生成
=> article_id
にインデックスを付与
データ取得
Post.all
=> 全てのデータを取得するメソッド。
Post.first
=> idがもっとも新しいデータセットを取得するメソッド。
Post.last
=> idがもっとも古いデータセットを取得するメソッド
Post.find
=> idを検索キーとしてデータを取得する。
=> 該当データがない場合エラーが返る。
Post.find_by()
=> idを含む様々な条件で検索するメソッド
=> 複数条件でも検索可能だが、結果は一件のみ。
=> 該当データがない場合nilが返る。
Post.where()
=> id以外の条件で検索するメソッド。
=> 該当するデータ全てが返ってくる。
Post.includes(:user)
=> N+1問題を解決してPostにUserをjoinしたデータが取得できる。
link_to
link_to('リンク名', posts_path)
link_to('リンク名', controller: 'posts', action: 'index'
=> 現在と同じコントローラのアクションにしない場合に利用される。
link_to('リンク先', '/posts')
<%= link_to('Destroy', post_path(post), method: :delete, data: { confirm: 'Are you sure?' }) %>
=> 削除時にアラート画面を出しながら削除。
Form
Rails5からform_tag
やform_for
に代わってform_with
が標準化される。
二つが統合したと考えて良くて、かなり構造的に似たものとなった。
<%= form_with url: post_path, scope: :post do |form| %>
<%= form.label :title %>
<%= form.text_field :title %>
<%= form.submit %>
<% end %>
=> scope
を使うことによって、params[:scope名][:title]
みたいなアクセスの仕方ができる。
=> 要はパラメータをグループ化してくれる。
<%= form_with model: Post.new do |form| %>
<%= form.label :title %>
<%= form.text_field :title %>
<%= form.submit %>
<% end %>
=> modelを使う場合は、urlとscopeを自動的に推測してくれる。
Strong parameters
データの受け渡しをパラメータでする際に、何のチェックもしないのは攻撃の絶好の対象となってしまうため対策する。
Railsにはそのセキュリティを高めるための考えとしてStrong Parametersというものがある。
なお、通常同一コントローラー内で複数回パラメータのやり取りはするため、共用できるようにメソッドを切り出し、なおかつprivate
にすることが多い。
def create
@post = Post.new(post_params)
if @post.save
end
end
def update
@post = Post.find(params[:id])
if @post.update(post_params)
end
end
private
def post_params
params.require(:スコープ名).permit(変数名)
end
Error
生成するオブジェクト(インスタンス)にエラーがある場合、
そのインスタンスメソッドのerrors
を利用して要因特定ができる。
主に、モデルクラスのvalidates
などの定義で問題があった場合に力を発揮する。
<% if @post.errors.any? %>
<%= pluralize(@post.errors.count, "error") occured %>
<ul>
<% @post.errors.full_messages.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
<% end %>
なお、エラーメッセージを含むフィールドは自動的にfield_with_errors
クラスを持つdivタグで囲まれます。
これを利用して、エラーメッセージをもっと目立たせるようにcssルールを定義できます。
Partial
方法1
アンダースコアつけたファイル名を作成。
_form.html.erb
などなど。
呼び出しは下記の通り。
<%= render 'form' %>
方法2
Nestingされている場合、下記のように呼び出すことができる。
views/comments/_comment.html.erb
のパーシャルを、
<%= render @post.comments %>
なお、パーシャルの中では、comment
という変数で紐づく内容を取得可能。
方法3
単純にviews/comments/_form.html.erb
を下記のように呼び出すことも可能。
<%= render "comments/form" %>
ビューを出力しているだけなので、パーシャルでもインスタンス変数を利用可能。
Nesting
ルーティングなどでネストされた関係を構築すると、
書くコード量をかなり減らすことができる。
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :article, foreign_key: true
t.timestamps
end
end
resources :articles do
resources :comments
end
has_many :comments, dependent: :destroy
=> dependent
を追加することで、記事が削除されたタイミングで関連するコメントも削除することができる。
belongs_to :article
def show
@article = Article.find(params[:id])
end
<%= form_with(model: [@article, @article.comments.build]) do |form| %>
...
<% end %>
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
...
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end