質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

include

あるファイルで定義された関数や処理を、別のファイル上でも使用できるようにするプロセスをincludeと呼びます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

2回答

2568閲覧

Rails ActiveDecoratorでconcerns配下にあるmoduleをdecorateしたい

Homaresan

総合スコア15

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

include

あるファイルで定義された関数や処理を、別のファイル上でも使用できるようにするプロセスをincludeと呼びます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

1グッド

1クリップ

投稿2021/04/22 04:25

編集2021/04/22 06:24

前提・実現したいこと

app/models/concerns配下にあるmodule(app/models/concerns/fruit.rb)が肥大化していたので、ActiveDecoratorを用いてviewの描画でしか使われていないようなメソッドをデコレーター層に切り離したいです。

イメージとしては下記のようにapp/decorators/concerns/fruit_decorator.rbを作成しfruit.rbからfruit_decorator.rbにメソッドを移し利用できるようにしたいです。

app/decorators/concerns/fruit_decorator.rb module FruitDecorator extend ActiveSupport::Concern def full_name "#{first_name} #{last_name}" end end

※ fruit.rbには他にもたくさんのメソッドがありますが一例としてviewの描画でしか使われていないfull_nameメソッドのみ定義してみました。

現状

module

app/models/concerns/fruit.rb module Fruit extend ActiveSupport::Concern def full_name "#{first_name} #{last_name}" end end

moduleをincludeしているモデル

app/models/apple.rb class Apple < ApplicationRecord include Fruit end
app/models/grape.rb class Grape < ApplicationRecord include Fruit end
app/models/banana.rb class Banana < ApplicationRecord include Fruit end

試したこと

app/decorators/concerns/fruit_decorator.rb module FruitDecorator extend ActiveSupport::Concern def full_name "#{first_name} #{last_name}" end end

上記、前提・実現したいことに記載のようにfruit_decorator.rbを作成しfruit.rbからfruit_decorator.rbにfull_nameメソッドを移しました。
その後、下記のようにviewでfull_nameメソッドを使用しましたが、エラーが出てしまいdecorator層に定義したメソッドを呼び出すことができませんでした。

app/views/apples/index.html.erb <% @apples.each do |apple| %> <%= apple.full_name %><br> <% end %>
エラー文 ActionView::Template::Error - undefined method `full_name'

補足情報(FW/ツールのバージョンなど)

  • Rails 6.0.3.5
  • gem "active_decorator"
shinoharat👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/04/22 05:49 編集

> 上記、前提・実現したいことに記載のfruit_decorator.rbですが、Fruitはclassではなくmoduleなので当然full_nameメソッドは呼ばれませんでした。 この表現が意味わからないのですがどう言う事ですか? どういう風に呼んでどう失敗したのですか? > イメージとしては下記のようにapp/decorators/concerns/fruit_decorator.rbを作成しfruit.rbからfruit_decorator.rbにメソッドを移し利用できるようにしたいです。 現状ですとこの質問に対して、すれば良いじゃんという回答以外思い浮かばない感じです。 何が出来ないのかがちょっとわからないです。
Homaresan

2021/04/22 06:26

ご指摘誠にありがとうございます! どういう風に呼んでどう失敗したのか記載しました!
guest

回答2

0

すみません、ActiveDecoratorを使ったことが無いので自信ないんですが、

まず、公式の説明読みましたか?(https://github.com/amatsuda/active_decorator)

僕もさっきパッと見ただけなので間違ってるかもしれませんが、公式のexmpleを読む限り、特にIncludeとかしてないので、多分命名で自動判別してるんだと思います。

例えばBookDecoraterであればBookモデルにincludeされる様な形で実装されてる気がします。
なので、FruitDecoraterのメソッドをAppleモデルで使える様にするのは多分無理か、なんか明示的に設定しないとダメな気がします。

ActiveDecoraterを使わなければ良いと思うのですが、使わなければいけない理由あるんでしょうか?

投稿2021/04/22 08:28

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/04/22 08:31

あ、すみません追記ですが、 各モデルのDecoraterを別々に定義してFruitDecoraterをincludeなりなんなりすれば出来る気がします。
Homaresan

2021/04/22 10:41

> なので、FruitDecoraterのメソッドをAppleモデルで使える様にするのは多分無理か、なんか明示的に設定しないとダメな気がします。 > 各モデルのDecoraterを別々に定義してFruitDecoraterをincludeなりなんなりすれば出来る気がします。 やはりそうするしかなさそうですね、、、 絶対にActiveDecoraterを使わなければならない理由は特に無いのでもう少し検討してみます。 ありがとうございました。
shinoharat

2021/04/27 04:05 編集

軽くソースコード読んだ感じ、 1・コントローラーのインスタンス変数をチェック 2・もし ActiveRecord::Base のインスタンスなら、クラス名に "Decorator" を付与したモジュールを探す (例: Apple → AppleDecorator) という実装でした。 (モデルクラス名のみ命名規則に影響し、コントローラー名やインスタンス変数名は無関係) https://github.com/amatsuda/active_decorator/blob/825588367448f823e28f56da613055a76f1e63a3/lib/active_decorator/decorator.rb#L68 なので benza さんの推測の通りですね。 オプション指定でどうにかなる感じでもないです。
shinoharat

2021/04/27 04:22 編集

対応方法ですが、私も > 各モデルのDecoraterを別々に定義してFruitDecoraterをinclude で良いんじゃないかと思います。 しかし、まだ回答受付中ということは、上記の方法だと解決しない問題があるのでしょうか? 例えば、 「includeが1行あるだけのデコレータを大量に定義するのに心理的な抵抗がある。gem "active_decorator" にこだわらないので、もう少し記述量を抑えられる方法を教えてほしい」 とか 「実際にモデルごとのデコレータを作ったけどやっぱり undefined method `full_name' になった」 とか 問題点についてもう少し詳しく教えてもらえると答えやすいです。
guest

0

Decoratorを使わずに似たようなことをしています。
というのは、modelでは使わないがviewのみで使うわけでもない、CSV書き出しとかにもつかう、というようなmethodを切り出すために。

FruitDecorator のようなもの(Decoratorというサフィックスがあとでなにかあるといやだから)を作って、model Apple にincludeする
という方法はどうでしょう

投稿2021/05/02 13:41

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問