LoginSignup
0
0

More than 5 years have passed since last update.

Rails チュートリアル メモ 第13章

Posted at

メモ

references

$ rails generate model Micropost content:text user:references

のように、モデルの generate 時に references 型を指定すると、外部キー参照付きのカラムが作られる。また、Micropost モデルに

  belongs_to :user

が自動的に追記される。これによって、Micropost のインスタンスに user メソッドが生えて、micropost.user のように関連するユーザーを参照することができるようになる。

たぶん xxx_id の xxx の部分が重要なんだろう。

belong_to / has_many

belongs_to / has_many の関係を設定することで、チュートリアル中の 表13.1 のようなメソッドが使えるようになる。このうち1つはすでに前述した。

重要なのは、所有側(今回でいう User)に user.microposts.create のようなメソッドが生えることである。これを使うと、user_id が初めから埋まった状態で Micropost のインスタンスを作ることができる。むしろ、Micropost のインスタンスは そのようにして作るのが慣習 らしい。

# 慣習的に間違い
@micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id)

# 慣習的に正しい
@micropost = @user.microposts.build(content: "Lorem ipsum")

buildcreate と違って DB に保存しない。細かいところでいうと、@user.micropost **s** のように複数形であることに注意。 has_MANY だからね。

belong_to は Micropost モデルの generate 時に自動的に記述されたが、User クラスに has_many を書くところまではやってくれないので、そこは自分で書く必要がある。

並び順の制御

default_scope を使う。

チュートリアルでは default_scope を並び順の制御にだけ使っているが、そのためだけの機能ではないんだろうなと思う。詳細は こちら を参照。何となく、DB から検索するときの SQL にデフォルト条件を設定するようなイメージっぽい。

親を消したときの子の扱い

親側のモデルで設定する。具体的には has_many にオプションを渡す。

dependent: :destroy を渡すと、親(user)が消えたときに子(microposts)も消す。DB にゴミが残らないのでスッキリする。他にもいくつか選択肢があるんだろうな。

DB の操作

User.order(:created_at).take(6)

Rails から DB を操作するときは、上記のようにメソッドチェーンを使う。
take と似た働きのメソッドとして limit がある。take は User のインスタンスの配列が得られるが、limit で得られるのは ActiveRecord::Relation クラスのオブジェクトである。

・・・とここまで書いてからわかったけど、take は ruby の Enumerable に定義された標準メソッドでした。

Fixture 同士の関連付け

orange:
  content: "I just ate an orange!"
  created_at: <%= 10.minutes.ago %>
  user: michael

上記のような micropost の Fixture を書くと、自動的に user の Fixture から michael を探して関連付けてくれる。user_id ではなく user なところにも注意。Rails のこういう仕様を把握しきれる自信がない。

resources によるルーティングの only オプション

route.rb で resources を使ってルーティングを定義すると、RESTful なルートが片っ端から用意されてしまうが、今回のように「create と destroy しか使う気がない」という場合は、only オプションで絞ることができる。

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

DB の操作2

where 句は以下のように使う。

Micropost.where("user_id = ?", id)

ここで重要なのが ? の利用だ。こうすることで、変数の中身がエスケープされて展開されるらしい。つまり SQL インジェクションの危険性が減る。下記のようにしないよう注意。

# ダメな例!
Micropost.where("user_id = #{id}")

簡易 friendly redirecting

request.referrer を使えば可能。ログインの場合はログイン画面が request.referrer に入ってしまうのでダメだが、ポスト削除の場合は削除画面を経由したりすることがないので、これで十分。

redirect_to request.referrer || root_url

|| を使って、request.referrer が空だったときのケアをしている。rails 5 からは redirect_back(fallback_location: root_url) でもいいらしい。

バリデーションの自作

  • validates ではなく validate なので注意(s がつかない)
  • データをチェックして、不正だったら errors.add するようなメソッドを作って登録する
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0