0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rails] MVCモデルを深ぼる~Model編~

Posted at

##はじめに
今回はModelについて少し踏み込んだ内容をアウトプットしていきたいと思います。
よろしくお願いします。

##モデルの役割とActive Model
モデルはコントローラーから命令されてデータを保存したり、データベースからデータを引っ張り出してくれたりします。またデータの加工を行ってくれたり、保存する前にデータの検証も行ってくれる役割があります。

モデルの「データをデータベースへ保存する」という機能はActive Recordという仕組みによって実現されています。
「保存する前のデータの検証」Active Modelという仕組みによって実現されています。すなわちモデルはこの二つの仕組みによって構成されています。

もう少し細かく、それらActive ModelとActive Recordが持っているモジュールをいくつかみて、モデルの理解を深めていきます。

Callbacksモジュール

Callbacksモジュールは必要なタイミングや、任意のタイミングでコールバックを定義することができます。
※ここでいうコールバックとは任意のタイミングで実行できる処理のことを指します。

コールバックはメソッドを定義するのと同じように登録します。下記に例を載せておきます。

class Tweet < ApplicationRecord
 validates :text, presence: true
 belongs_to :user
 has_many :comments

 # バリデーションの後で「puts_sample」を実行
 after_validation :puts_sample

 # 「puts_sample」というcallbackを登録
 private
   def puts_sample
     puts 'sample'
   end
end

after_validationという記述でバリデーションが行われた後に実行するように指定しています。

##Validationsモジュール
バリデーションはデータベースへデータを保存する際に、保存してもいいデータなのか(期待通りのデータの形なのか)判断するために用いられるフィルターのようなものです。
もし、誤ったデータであるなら、バリデーションが弾いてくれます。

例えば、validates :text, presence: true と書いて、textが空なら保存しないようにするやつです。

##Serializationモジュール
Serializationモジュールは値を返す時に整えて返してあげることがモジュールです。
どういうことかというと、一つのレコードに5種類のデータ(カラム)が存在していたとして、しかし、必要なデータはその中の二つだけだったとしたら、残りの三つは不要なのでそのデータは含めないように整えてくれるのです。

例のコードをを下記に載せておきます。

コントローラーでこのようなindexアクションが定義されているとします。

class TweetsController < ApplicationController
  def index
    @tweets = Tweet.includes(:user).order("created_at DESC")
    render json: @tweets
  end
end

これはJSON形式で値を返しています。
中身は下記のようになっているとします。

[
  {"id":2,"text":"太陽の写真","image":"data:image/sample","created_at":"2020-04-22T06:11:44.134Z","updated_at":"2020-04-22T06:11:44.134Z","user_id":1},
  {"id":1,"text":"綺麗な景色","image":"data:image/jpeg;base64,/9j","created_at":"2020-04-22T06:11:25.425Z","updated_at":"2020-04-22T06:11:25.425Z","user_id":1},
]

しかしながら必要なのはtextとimageだけだったら、モデルにattributesメソッドを用いて下記の記述をすると、textとimageだけの値を返却することができます。

  def attributes
    {'text' => nil, 'image' => nil}
  end

このようにすることで、余分な情報がないので扱いやすくなります。

##Formオブジェクト

Formオブジェクトは、例えば、一度の投稿作業で(投稿ボタンのクリック一回で)複数のテーブルへ情報を更新したりする時に役立ちます。フォームに関する処理を切り出す仕組みです。

フォームに入力されている情報が複数のモデルに関係するデータで、一回で複数モデルを操作し、データを更新したい時(投稿機能)や、フォームに入力された情報に対するモデルが存在しないがバリデーションをかけたい時(検索機能)などに使用します。

使用方法は別記事で書きたいと思います。

##終わりに
3回にわたって、MVCモデルを少し踏み込んでみました。自分自身、新しく知れたことや、いまだに理解が浅いところが浮き彫りになり、このように記事をまとめる機会を作れてよかったと感じています。特に理解し難い部分や詳細に説明できなかった部分に関しては、オブジェクト指向の概念がしっかりと理解しきれていないことに起因していると思います。

このような基礎的な部分はこれからもねちっこく付き合って理解していきたいと思っています。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?