【Rails】Railsのmodel、controller、そしてattr_accessorについて

# はじめに
Rubyではattr_accessorを用いることで、クラスの外でもインスタンス変数の読み取り及び書き込み（変更）ができます。これを踏まえRailsのモデルでattr_accessorメソッドにより宣言した変数の動きと気づいた点について考えてみました。(個人的な見解であり、間違った部分に関してはご指摘いただければ幸いです）

# 目次
- ModelのクラスとControllerとの関係
- attr_accessorメソッドとクラスの外の意味
- attr_accessorで宣言した変数はcontrollerでどういう働きをするのか
- 参考サイト

# ModelのクラスとControllerとの関係
Modelはデータベースの設計図のようなものであり、データベースの情報が記録されています。RailsのControllerではModelで定義したクラスや変数、メソッドを呼び出し利用することが可能です。
例えば、Boardモデルにboardsコントローラーがある場合、

①board.rb(モデル）

```ruby

class Board < ApplicationRecord
  belongs_to :user
  # belongs_to :admin
end
```
モデルにはBoardクラスがあります。BoardクラスはApplicationRecordを継承していて、ApplicationRecordで定義したメソッドを全て利用可能です。

②boards_controller.rb（コントローラー）

```ruby
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ファイル

```ruby

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メソッドを実行してみました。

②結果
![スクリーンショット 2021-02-03 22.58.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/99e0e6e5-0b88-e6e9-2892-c16dd20b7eea.png)
ターミナルで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を定義します。

```ruby
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))

```ruby
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