Close icon
2023月06日30日

[Rails]ActiveDecoratorをControllerで使う

環境

Rails 6.1.7.2

やりたいこと

  • プログラムのコードをcodeタグを使って表示するため、コードの行ごとにspanタグを追加したい。
  • spanタグの追加処理はDecoratorで実装したい。
  • プログラムのコードはAPIで取得しているため、コントローラーでDecoratorを使用したい。

実装方法

sample_codesテーブルのsourceにプログラムのソースがテキストで保存します。
Decoratorにソースコードの1行ごとにspanタグを追加するメソットsource_codeを実装します。

SampleCodeDecorator

  
module SampleCodeDecorator
  def source_code
    lines = source.split("\n")
    source_code = ''
    lines.each do |line|
      source_code += "#{line}"
    end
    source_code
  end
end
  

APIのコントトーラーからSampleCodeDecoratorのメソッドsource_codeを実行するとエラー

sample_codes_controller.rb(修正前)

  
class Api::SampleCodesController < Api::ApiController
  def source
    sample_code = SampleCode.find(params[:sample_code_id])

    response = {}
    response[:title] = sample_code.title
    response[:source_code] = sample_code.source_code

    render json: response
  end
end
  

この状態で実行するとundefined methodになってしまいます。

NoMethodError (undefined method `source_code' for # Did you mean? source): app/controllers/api/sample_codes_controller.rb:8:in `source'

Viewで使用する時はActiveRecordのオブジェクトからDecoratoerのメソッドが自動的に実行されますが、コントローラーでActiveDecoratorを使いたい場合は、Decoratorのインスタンスを生成して使用します。

コントトーラーでDecoratorを使用する

sample_codes_controller.rb(修正後)

  
class Api::SampleCodesController < Api::ApiController
  def source
    sample_code = SampleCode.find(params[:sample_code_id])

    # ActiveRecordのオブジェクトからDecoratorを生成する。
    decorater = ActiveDecorator::Decorator.instance.decorate(sample_code)

    response = {}
    response[:title] = decorater.title
    response[:source_code] = decorater.source_code

    render json: response
  end
end
  

コードにspanタグを追加してAPIのレスポンスとして返しています。

実行結果



アトトックラボとは

株式会社アトトックメンバー が技術の話、デザインの話、キャラクターの話、ときどき脱線してガジェットの話やライフハックの話など好きなことを書いています。


連載記事


最近の記事


タグ