例えば以下の様にモデルとコントローラーがあるとします。
モデルクラスにはコンストラクタ(initialize method)を付け加えており、インスタンス化したさいに自動的にidをセットするようにします。
class Hoge < ApplicationRecord def initialize(id) @id = id end def hoge Hoge.where(id: @id) end end class HogesController < ApplicationController def create fuga = Hoge.new(current_user.id) @foo = fuga.hoge Hoge.new(id: current_user.id, another: id, delflag: 1) Hoge.save! end end
ここで質問なのですが
hogeというHogeクラスに記載されているインスタンスメソッドを使いたい際は、
fuga = Hoge.new(current_user.id) foo = fuga.hoge
のような形でインスタンスメソッドを呼び出せると思います。
同じく、モデルを保存したい時はnewメソッドを用いてインスタンスオブジェクトを生成すると思いますが、
保存したいモデルの属性をnewメソッドの引数に取るに辺り、自前で実装したコンストラクタの引数と数が異なっていると思います。
Hoge.new(current_user.id) #1つ Hoge.new(id: current_user.id, another: id, delflag: 1) #3つ
このせいかは良く分かっていないのですが、new,save!メソッドを使用すると以下のようなエラーが出ている状態です。
undefined method `[]=' for nil:NilClass (NoMethodError)
よくよく思うとネットのリファレンスを見るにあたり、initializeメソッドをモデルクラスに記述しているものを見たことが無く
自分の実装方法が合っているのか気になります。
質問をまとめると
①以上の様に異なる用途でnewメソッドを用いたい際に引数が異なっていても問題がないか
②createする際のインスタンスオブジェクト生成のnewとインスタンスメソッドを使用したい際のnewは何が違うかということです(原則同じことをやっているのでしょうけど、なにか継承元のApplicationRecordクラスが悪さをしている気がします。。。)
長くなってしまいましたがよろしくお願いいたします。
追記
MVCにおいてはビジネスロジックはモデルに書いてモデルを太らせるのが鉄則といいますが、
以下のようにのようにモデルクラスに複数メソッドを書き、where句等で同じ変数を用いたい際にコンストラクタがあるとインスタンスメソッドを呼び出す際に書き方がスッキリして便利だと思うのですが、モデルクラスでコンストラクタを使いたい際はどのようにするのがベストなのでしょうか。
#コンストラクタあり class Hoge < ApplicationRecord def initialize(id) @id = id end def hoge Hoge.where(id: @id) end def hoges Hoge.includes(:bar).where(id: @id) end end #コンストラクタなし class Hoge < ApplicationRecord def hoge(id) Hoge.where(id: id) end def hoges(id) Hoge.includes(:bar).where(id: id) end end
それともそもそもrailsのモデルクラスの場合はPOCOではないのでロジックをあまり書くべきではないのでしょうか?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/26 01:59
2019/07/26 02:26
2019/07/26 02:28
2019/07/26 02:30
2019/07/26 02:43