はじめに
Rubyではattr_accessorを用いることで、クラスの外でもインスタンス変数の読み取り及び書き込み(変更)ができます。これを踏まえRailsのモデルでattr_accessorメソッドにより宣言した変数の動きと気づいた点について考えてみました。(個人的な見解であり、間違った部分に関してはご指摘いただければ幸いです)
目次
- ModelのクラスとControllerとの関係
- attr_accessorメソッドとクラスの外の意味
- attr_accessorで宣言した変数はcontrollerでどういう働きをするのか
- 参考サイト
ModelのクラスとControllerとの関係
Modelはデータベースの設計図のようなものであり、データベースの情報が記録されています。RailsのControllerではModelで定義したクラスや変数、メソッドを呼び出し利用することが可能です。
例えば、Boardモデルにboardsコントローラーがある場合、
①board.rb(モデル)
class Board < ApplicationRecord
belongs_to :user
# belongs_to :admin
end
モデルにはBoardクラスがあります。BoardクラスはApplicationRecordを継承していて、ApplicationRecordで定義したメソッドを全て利用可能です。
②boards_controller.rb(コントローラー)
class BoardsController < ApplicationController
(前略)
def create
board = Board.create(post_params)
end
(後略)
end
コントローラーではモデルで宣言したクラス「class Board」を利用できます。BoardクラスはApllicationRecordを継承しているのでApplicationRecordの中にあるメソッド、createを呼び出すことができます。例ではboard変数にモデルのBoardクラスメソッド(ApplicationRecordを継承したメソッド)createを使いパラメーター(post_params)を保存しています。このようにRailsのControllerではModelのクラスとメソッドが利用可能です。
attr_accessorメソッドとクラスの外の意味
attr_accessorはクラスのインスタンス変数をクラスの外で読み取り&書き出しができるようにするメソッドです。ここでいう「クラスの外」どこまででしょうか。例えば、他のクラスの中でも読み書きできるのか。実際にやってみました。
①attr.rbファイル
class Greeting
attr_accessor :name #を定義
end
class SuperGreeting
def hi
person = Greeting.new
person.name = "Tom" #「オブジェクト名.変数名 =」で代入
puts person.name
end
end
sayname = SuperGreeting.new
sayname.hi
Greetingクラスでattr_accessorメソッドで変数:nameを定義します。これをSuperGreetingクラスのhiメソッドでGreetingのインスタンスpersonを生成し、personのname変数を"Tom"に書き込みます。それをperson.nameで呼び出します。結果を確認するために、SuperGreetingのインスタンスsaynameを生成し、hiメソッドを実行してみました。
②結果
ターミナルでattr.rbを実行してみたら「Tom」が出力されました。ということはattr_accessorメソッドの「クラスの外」という意味は他のクラス内も「外」であり、読み書きができることを意味します。
attr_accessorで宣言した変数はcontrollerでどういう働きをするのか
以上を踏まえRailsのModelでattr_accessorで定義した変数はControllerで読み書きができるのかについて考えてみました。結論からいうと可能です。なぜなら、①ControllerはModelのクラスが利用可能、②attr_accessorメソッドで定義した変数は他のクラス(クラスの外)でも利用可能であるからです。attr_accessorはrailsではformオブジェクトで以下のような使い方が考えられます。(元となるモデルファイルは省略します)
①sdateboard.rb(モデル)
モデルでattr_accessorで:name,:comment,:date,:timeを定義します。
class SdateBoard
include ActiveModel::Model
include ActiveRecord::AttributeAssignment
attr_accessor :name, :comment, :date, :time
def save
sy = Sdate.create(:date, :time)
Board.create(name: name, comment: comment, sdate_id: sy.id)
end
end
②boards_controller.rb(コントローラー)
sdateboard.rbモデルのクラスSdateBoardをboards_controller.rbコントローラーのcreateメソッド内で使っています。(@sdate_schedule = SdateBoard.new(schedule_parmas))また、sdateboard.rbモデルでattr_accessorで定義した変数「:name, :comment, :date, :time」はコントローラーのクラスBoardsControllerのschedule_paramsメソッド内で使われています。(params.reuqire(:sdateboard).permit(:name, :comment, :date, :time))
class BoardsController < ApplicationController
(前略)
def create
@sdate_schedule = SdateBoard.new(schedule_params)
@sdate_schedule.save
redirect_to new_schedule_path
end
private
def schedule_params
params.require(:sdateboard).permit(:name, :comment, :date, :time)
end
(後略)
end
以上でmodelとcontrollerの関係とattr_accessorで定義した変数の動きを確認することができました。
参考サイト
https://techacademy.jp/magazine/41659
https://pikawaka.com/ruby/attr_reader
http://pikawaka.com/ruby/attr_accessor