Rails チュートリアル読んでみた(その4)
第12章 パスワードの再設定
- rails generate controller コントローラ名 アクション名 ... --no-test-framework
: コントローラの単体テストを作らないでコントローラを作成するコマンド
- モデルオブジェクト.errors.add(:カラム名, :blank)
: モデルオブジェクトの特定のカラムにバリデーションエラー(今回は空だった時のエラー)を設定するメソッド
- response.body
: リクエスト先のHTML本文を返すメソッド。テストで使用
- メイラーが作成するメール内容を構造的に取得する方法(主にテストで使用)
-
メールオブジェクト.subject
: メールのタイトル取得。 -
メールオブジェクト.to
: メールの宛先を取得。 -
メールオブジェクト.from
: メールの送信元を取得。 -
メールオブジェクト.body.encoded
: メールの本文を取得。
第13章 ユーザーのマイクロポスト
- % rails generate model モデル名 カラム名:データ型 ... モデル2名:references
: モデル2とblongs_to関係を持つモデルを作成する為のコマンド
- default_scope -> { order(カラム名: :desc) }
: モデル内に記述。テーブルのレコードの初期の並び順を特定のカラムの値の降順に変更する
- htmlの <ul>
タグと <ol>
タグはどちらもリストを作成するが、前者は順序無し、後者は順序付きでそれぞれリストを作成する
- test用テーブルのレコード(fixtures)にbelongs_to関係を紐付けるには test/fixtures/テーブル名.yml
に以下のように記述。
シンボル名: カラム名: 値 カラム2名: 値 ︙ belongs_to関係にあるテーブルAの単数形: 紐付けたいテーブルAのfixturesのシンボル名
- <%= render ‘パーシャルまでのpath’, パーシャル内での変数名: 渡す変数 %>
: パーシャルに渡す変数の名前をパーシャル内で新しい変数名に変更する為の書き方
- request.referrer
: 現在のリクエストのひとつ前のリクエストのURLを返すメソッド
- 画像の管理を行うアップローダー CarrierWave
の導入方法
-
carrierwave
,mini_magic
,fog
と言う3つのgemをbundleインストール。この時fog
gemは本番環境:production
グループのみにインストール1。 -
% rails generate uploader アップローダー名(キャメルケース)
コマンドでアップローダーapp/uploaders/アップローダー名(スネークケース)_uploader.rb
を作成。 - 画像データを保存するモデルAに
picture
というstring型のカラムを作成。 - モデルAの
picture
にアップローダーを紐付けるためにapp/models/モデルA.rb
にmount_uploader :picture, アップローダー名(キャメルケース)Uploader
を記述。 - railsサーバーを再起動。具体的には
% spring stop
コマンド実行後にrails console
を実行。
<%= form_forのイテレータ.file_field :picture %>
: フォームの file_field
タグに picture
を渡す事で画像投稿フォームを作成。
<%= image_tag モデルAのレコードオブジェクト.picture.url if モデルAのレコードオブジェクト.picture? %>
: image_tag
に picture.url
を渡す事で画像を表示。 picture?
メソッドは、レコードオブジェクトの picture
カラムに画像データがあるかどうかを判定するメソッドであり、アップローダーに付随して作られる。
picture.size
: アップロードされたファイルのバイト数を返すメソッド。
- アップローダー CarrierWave
にアップロード出来るファイルの形式を制限する方法
app/uploaders/アップローダー名(スネークケース)_uploader.rb
に書かれている以下の部分をコメントアウトする。
class PictureUploader < CarrierWave::Uploader::Base ︙ def extension_whitelist %w(jpg jpeg gif png) end ︙ end
次に、画像投稿フォーム(form_forのfile_fieldタグ)にacceptオプションで受け付けるファイル形式のMIMEタイプを記述する。例えば、受け付けるファイル形式がjpeg、gif、pngだった場合は、以下のようになる。
<%= form_forのイテレータ.file_field :picture, accept: ‘image/jpeg,image/gif,image/png’ %>
- validate :validationメソッド名
: オリジナルのvalidationをモデル内で宣言する方法。モデル内でvalidationメソッドを作り、そのメソッド内でカラム判定を行い、条件に合わない値が入った時、 errors.add(:カラム名, “エラーメッセージ”)
のようにエラーメッセージを作成する事が出来る
- アップローダー CarrierWave
にアップロードされた大きい画像を自動リサイズする方法
- 開発環境に
ImageMagick
をインストール。LinuxOSの場合は% sudo yum install -y ImageMagick
で。 -
app/uploaders/アップローダー名_uploader.rb
に以下を書き込む。
class PictureUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick process resize_to_limit: [400, 400] ︙ end
MiniMagick
は ImageMagick
ツールを Ruby
で操作するためのgem。上のプログラムはアップロードされた画像サイズの横か縦が400pxを超えた時に、適当なサイズにリサイズしてくれる物である。他の操作方法はこことかここを参照。
- アップローダー CarrierWave
のリサイズ機能をテストの時は無効に設定する方法
config/initializers/skip_image_resizing.rb
に以下のように記述。もっと詳しく知りたい場合はドキュメント参照。
if Rails.env.test? CarrierWave.configure do |config| config.enable_processing = false end end
- 本番環境(heroku)でのアップロード画像の保存先をAWSのS3(クラウドストレージ)にする方法2
1. app/uploaders/アップローダー名(スネークケース)_uploader.rb
のアップロード画像の保存形式 strage :file
を本番環境で fog
を使用するために以下のように書き換える3。
class PictureUploader < CarrierWave::Uploader::Base ︙ if Rails.env.production? storage :fog else storage :file end ︙ end
2. AWSのS3にIAMユーザを設定。
3. config/initializers/carrier_wave.rb
に以下を記述4。
if Rails.env.production? CarrierWave.configure do |config| config.fog_credentials = { # Amazon S3用の設定 :provider => 'AWS', :region => ‘S3のREGION’, :aws_access_key_id => ‘IAMユーザのACCESS_KEY’, :aws_secret_access_key => ‘IAMユーザのSECRET_KEY’ } config.fog_directory = ‘S3バケット名’ end end
4. git heroku master
を更新。
第14章 ユーザーをフォローする
- テーブルAがテーブルB(関係付け)を介してテーブルAのレコードを取得するリレーション関係の作成
上図のように、テーブルAのレコード同士がある関係性(テーブルBの関係性aと関係性b)で結びついている時、そのリレーションモデルは、以下のように作成する。
1. app/models/モデルA.rb
に以下の内容を書く。上図の赤矢印の関係を構築。
has_many :シンボル名, class_name: “モデルB”, foreign_key: “関係性a_id", dependent: :destroy
2. app/models/モデルB.rb
に以下の内容を書く。上図の青矢印の関係を構築。
belongs_to :関係性a, class_name: “モデルA” belongs_to :関係性b, class_name: “モデルA”
3. app/models/モデルA.rb
に以下の内容を書き加える5。上図の赤矢印の結果からの青矢印の関係を構築。
has_many :シンボル2名, through: :シンボル名, source: :関係性b
テーブルAのレコードオブジェクト.シンボル名
: テーブルBのレコードの内、レコードオブジェクトのid
と関係性a_id
が一致するレコード群を取得。テーブルAのレコードオブジェクト.シンボル名.build(関係性b_id: テーブルAのidの値)
: レコードオブジェクトのidと紐付いたテーブルBのレコードオブジェクトを作成。まだ、テーブルには追加していない。テーブルBのレコードオブジェクト.関係性a or 関係性b
: テーブルAのレコードの内、レコードオブジェクトの関係性a or 関係性b_id
とid
が一致するレコードを取得。テーブルAのレコードオブジェクト.シンボル2名
: テーブルAのレコードの内、レコードオブジェクトのid
とテーブルBの関係bを持つ全てのレコード群(青矢印の先の全てのレコード)を取得。配列なので、include?メソッドなどが使用可能。テーブルAのレコードオブジェクト.シンボル2名 << テーブルAの別のレコードオブジェクト
: テーブルBに新しいレコードを保存。実際にテーブルに反映済み。
- resources
(RESTfulリソース)に新たにリソース・id付きリソースを割り当てる方法( config/routes.rb
に以下を追加)
- リソース(
コントローラ名/アクション名
)の場合
resources :コントローラ名 do collection do get or post :アクション名 end end
- id付きリソース(
コントローラ名/id/アクション名
)の場合
resources :コントローラ名 do member do get or post :アクション名 end end
- テストで取ってきたページコードは文字列なので assert_select ページ上のタグ, text: レコードのカラム値(string型以外)
や assert_match レコードのカラム値(string型以外), response.body
などは型が違うのでエラーになる。テーブルから取ってきた値の後ろには to_s
メソッドを必ず付けるべし
- form_for
の処理をAjaxを使った非同期処理に変える(コントローラの処理をページの遷移無しに別プロセスにやらせる)方法
1. form_for
に remote: true
タグを追加6。
2. 対応するアクションに以下のコードを最後に追加。
def アクション名 ︙ 処理内容 ︙ respond_to do |format| format.html { redirect_to 元のページ } format.js end end
3. config/application.rb
に以下のコードを追加し、ブラウザ上でJavaScriptが無効になっていた場合に対応する。
︙ module Railsアプリ名 class Application < Rails::Application ︙ config.action_view.embed_authenticity_token_in_remote_forms = true end end
4. app/view/コントローラ名/対応するアクション名.js.erb
にアクション処理後にページ内で書き換えたいコードをJavaScriptで書く。書き方は以下。
$(“書き換えたいHTML要素をCSSの文法で指定”).html("<%= アクション処理後のコードを記述 %>");
- escape_javascript(エスケープするコード)
: 与えられたコードをjavascriptの文法でエスケープする(コード内の特殊文字を普通の文字として扱う)為のerbメソッド。このメソッドを使う理由はここを参照。
- テスト上で、Ajaxの非同期処理に対してリクエストを作成する時は post リクエストパス ..., xhr: true
のように、xhr (XmlHttpRequest) オプションをtrueに設定する
- モデル名.where(“カラム名 = #{変数}”)
と書いた場合、変数の値に不正なSQLコードを書かれると、アプリ内でその実行を防ぐことが出来ない7。なので モデル名.where(“カラム名 = ?”, 変数)
と書いて変数の中身をエスケープ(SQLコードに必要な特殊文字の打ち消し処理)をさせ、実行を防ぐ方法がある。また、変数の中身が配列の場合、丸括弧で囲って (?)
のように書く
- テーブルから取得する条件文(Where句やHaving句)に他のテーブルから取得したレコード群を使用する場合は、サブクエリを作成し、テーブルに接続する回数を一回のみにすると処理速度が速くなる
- ActiveRecordメソッド : モデル(データベース)へアクセスする為のメソッド
order(:カラム名)
: テーブルのレコードの順序をカラム名の値の昇順に並び替える。take(数値)
: テーブルの最初から数値分のレコードを取得。
- 便利なヘルパー
time_ago_in_words(タイムスタンプ)
: タイムスタンプが示す時刻と現在の時刻との差分(14 minutes
とかabout 1 years
など)を返すメソッド。fixture_file_upload(‘test/fixtures/ファイル名’, ‘ファイルの保存形式’)
:test/fixtures
内のファイルをアップロードするメソッド。ファイルの保存形式
にはアップロードするファイルに該当するMIMEタイプを記入。
-
mini_magic
は、画像をリサイズするgemで、fog
は、本番環境に画像をアップロードするためのgemである。↩ -
strage :file
はアップロード画像をローカルのファイルシステム(railsではpublic/uploads/
内)に保存し、strage :fog
はfogと言うクラウドシステムの操作を行う為のソフトウェアを使って、クラウドシステムに保存する。↩ -
has_many :関係性bの複数形, through: :シンボル名
のようにsource:
を省く事が出来るが、呼び出す時に使うメソッド名が関係性bの複数形になる。↩ -
remote: true
追加により生成されるHTMLコードにはdata-remote=“true”
タグが追加される。このタグはrailsにJavaScriptによるフォームの操作を知らせる。これにより、本来非同期処理に必要であるJavaScriptのコードをView内に書かずに済んでいる。↩