このQiitaはRubyを勉強している中で
私が「ずっと理解できていなかったこと」と「その理由」と「勉強して理解したこと」をまとめたものです。
まだまだ間違っている部分もあるかもしれないのと
私自身まだわからないところ( の部分 )もあるため
その点踏まえてみてください
ずっと理解できていなかったこと
MVCモデルについての理解
※以下、私の昔の理解なのでところどころ間違ってます!
・ルーティング…リクエストに対して適切な場所に移動させる役割。
ブラウザからリクエストが来る。リクエストに対してルーティングで送り先を、コントローラとアクションを指定。
・コントローラー…実装したい機能を決める場所。
・実装したい機能に対して適切なアクションを設定。その際にはRailsで決められてる7つのアクションのどれかに沿って決める。
【Rails】7つのアクションとそれぞれの役割
・そのアクションの中にDBからデータを持って来るために変数を定義しないといけない。それは@からはじまる。
・変数を定義するためにはrailsであらかじめ定められたメソッドで定義できるっぽい。
・ビュー…DBから送られてきたデータを表示する場所
・HTMLの中で <% %> とか <%= %> で囲むとコントローラーで定義した変数を使えるっぽい。そこは動的になる。
・それ以外は普通のHTMLとCSSを書いていくと静的になる。
・モデル…コントローラーからDBへの橋渡し役。DB設計に何か命令する役目?
・テーブル作成と同時にrails g modelをしなければいけない。
・modelを作成した後は特に編集とかは要らないっぽい。
・マイグレーションファイル…DB設計を記述するところ。
その他理解できなかったこと
・なぜクラスとインスタンスが存在するのか?
・MVCモデルにおいてクラスはどれをさしているのか?
・クラスからインスタンスが生成されるというのはMVCにおけるどの部分をさしているのか?
・controllerのアクションの中には何を定義するのか?
・引数はなんで使うのか?
なぜ理解をしていなかったか
Rubyでは、 すべてのデータがオブジェクトとして扱われ、オブジェクトごとに性質や使えるメソッドを持つ
という概念を理解していなかった。
(もちろんRubyを習い始めた時に、「オブジェクト指向」についての説明は出てきたが、その概念が初めてで理解できなかったし、そんなに大事なものだと思っていなかった。)
勉強して理解したいこと
勉強して理解ことを「User model」と「Tweet model」の2つをもつツイートアプリの例とともに説明。
モデルについて
モデルの存在意義
・データベースの設計図。そのデータベースに定義したいメソッドを書く場所。(アソシエーション、バリデーション、そのモデル独自のメソッドなど)
・そのためモデルはDB設計が必要なものしかつくらない。静的なサイトであればモデルはいらない。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable #ユーザーのログイン機能に関する記述
has_many :tweets #tweet modelに対するアソシエーション
validates :nickname, presence: true, length: { maximum: 6 } #バリデーション
end
class Tweet < ApplicationRecord
belongs_to :user #user modelに対するアソシエーション
end
Railsで定義されているメソッドの存在
・上記のようにモデルに記述がされていなくても、もともとrailsで定義されているメソッドがある。
①テーブルのカラム名
例えば、tweets tableを以下のように定義している場合
class CreateTweets < ActiveRecord::Migration[5.2]
def change
create_table :tweets do |t|
t.string :name
t.text :text
t.text :image
t.timestamps null: true
end
end
end
tweet modelには記述されていないが以下のようなメソッドが定義されている。
class Tweet < ApplicationRecord
belongs_to :user #user modelに対するアソシエーション
#以下、記述はされていないが使えるメソッド
def name
@name
end
def text
@text
end
def image
@image
end
end
②Application Recordクラスのメソッド(クラスの継承)
rails g modelコマンドで生成されるモデルクラスは全てApplicationRecordというクラスを継承している。
ApplicationRecordというクラスには テーブルにアクセスして情報を取得するためのメソッドが定義されており
、モデルクラスはそれを継承し利用することでテーブルから情報を取得している。
記述されていないがtweet modelには以下のようなメソッドが定義されている。
class Tweet < ApplicationRecord
belongs_to :user #user modelに対するアソシエーション
#以下、記述はされていないが使えるメソッド
def all
# ここの記述がわかんない
end
def new
# ここの記述がわかんない
end
def save
# ここの記述がわかんない
end
def create
# ここの記述がわかんない
end
end
それぞれの中に書いてある記述
コントローラーについて
コントローラーの存在意義
モデルに定義してあるメソッドを使う役割。
class UsersController < ApplicationController
def show
user = User.find(params[:id]) # User modelで最初から定義されているfindメソッドを用いてidを引数にuserを見つけて来る
@nickname = user.nickname # User modelで最初から定義されているnicknameをメソッド使って、user tableからnicknameを見つけてくる
@tweets = user.tweets.page(params[:page]).per(5).order("created_at DESC")
end
end
class TweetsController < ApplicationController
before_action :move_to_index, except: :index
def index
@tweets = Tweet.includes(:user).page(params[:page]).per(5).order("created_at DESC")
end
def new
end
def create
Tweet.create(image: tweet_params[:image], text: tweet_params[:text], user_id: current_user.id)
end
def destroy
tweet = Tweet.find(params[:id])
if tweet.user_id == current_user.id
tweet.destroy
end
end
def edit
@tweet = Tweet.find(params[:id])
end
def update
tweet = Tweet.find(params[:id])
if tweet.user_id == current_user.id
tweet.update(tweet_params)
end
end
def show
@tweet = Tweet.find(params[:id])
end
def search
@tweets = Tweet.search(params[:keyword])
respond_to do |format|
format.html
format.json
end
end
private
def tweet_params
params.permit(:image, :text)
end
def move_to_index
redirect_to action: :index unless user_signed_in?
end
end
アクション内の記述方法
Q.controllerのアクションの中には何を定義するのか?
AかBのいづれか。
A.モデルに定義してあるメソッドを使って、データを引き出す
B.モデルに定義してあるメソッドを使って、データを引き出しインスタンス変数を定義してビューに渡す
その際にUser ControllerではUser modelで定義されているメソッドもつかえるし、tweet modelで定義されているメソッドも使える。
クラスとインスタンス
Q.なぜクラスとインスタンスが存在するのか?
・Rubyでは、すべてのデータがオブジェクトとして扱われ、オブジェクトごとに性質や使えるメソッドを持つ
・オブジェクトを効率的に生成・管理するために、クラスとインスタンスという概念が存在する
・オブジェクト同士の共通の属性・メソッドをまとめて定義したものがクラスである
・クラスに基いて生成されたオブジェクトがインスタンス
例)Userモデルにはクラスとしてログイン機能をつけたり、ニックネームの登録の際のバリデーションをつけておく。
そこから実際に登録されたユーザー1人1人がインスタンス。
Q.MVCモデルにおいてクラスはどれをさしているのか?
・Controller
・Model
・table
(オブジェクトに共通の属性・メソッドを
まとめて定義したものはすべてクラス。)
Q.クラスからインスタンスが生成されるというのはMVCにおけるどの部分をさしているのか?
(Controllerで)Modelのメソッドを使うとき。
必ずインスタンスが生成される。
modelのメソッドを使うのはcontrollerだけでまちがいないか?
引数について
Q.引数はなぜ使うのか
メソッドを異なる条件によって使うため。
#このままだと毎回idが1のツイートしか編集できない
def edit
@tweet = Tweet.find(1)
end
#引数をわたすことによって様々なidのツイートの編集ができるようになる
def edit
@tweet = Tweet.find(params[:id])
end
以上。
間違っているところがあればご指摘ください。