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

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

ただいまの
回答率

87.78%

undefined method `id' for nil:NilClassのエラーについて

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 441

score 12

イメージ説明
RailsでPrawnを使ってPDF出力を作成しています。
https://ruby-rails.hatenadiary.com/entry/20140907/1410078997 を参考に作成していますが
undefined method `id' for nil:NilClass のエラーが出て解決できません。@orderにデータが入っていない との事だと思いますが記述を変えてみましたが解決できていません。対策わかる方いらっしゃればよろしくお願いします。

エラーの記述があるコード order_pdf.rbのtext "注文番号:  #{@order.id}"で エラーです。

class OrderPDF < Prawn::Document

  def initialize(order)
    super()

    font "vendor/fonts/ipaexm.ttf"
    text "こんにちは, Prawn!! on order_pdf.rb"

    # ヘッダー部分の表示
    header
    # ヘッダーリード部分の表示
    header_lead
    # テーブル部分の表示
    table_content
  end

  def header
    # size 28 で "Order"という文字を表示
    text "Order", size: 28

    # stroke(線)の色を設定し、線を引く
    stroke_color "eeeeee"
    stroke_line [0, 680], [530, 680]
  end

  def header_lead
    # カーソルを指定
    y_position = cursor - 30

    # bounding_boxで記載箇所を指定して、textメソッドでテキストを記載
    bounding_box([100, y_position], :width => 270, :height => 50) do
      font_size 10.5
      text "注文番号:  #{@order.id}"
      move_down 3
      text " 注文日:  #{@order.purchased_at}"
    end
  end

  def table_content
    # tableメソッドは2次元配列を引数(line_item_rows)にとり、それをテーブルとして表示する
    # ブロック(do...end)内でテーブルの書式の設定をしている
    table line_item_rows do
      # 全体設定
      cells.padding = 8          # セルのpadding幅
      cells.borders = [:bottom,] # 表示するボーダーの向き(top, bottom, right, leftがある)
      cells.border_width = 0.5   # ボーダーの太さ

      # 個別設定
      # row(0) は0行目、row(-1) は最後の行を表す
      row(0).border_width = 1.5
      row(-2).border_width = 1.5
      row(-1).background_color = "f0ad4e"
      row(-1).borders = []

      self.header     = true  # 1行目をヘッダーとするか否か
      self.row_colors = ['dddddd', 'ffffff'] # 列の色
      self.column_widths = [50, 200, 100, 70, 100] # 列の幅
    end
  end

  # テーブルに表示するデータを作成(2次元配列)
  def line_item_rows
    # テーブルのヘッダ部
    arr = [["#", "品名", "単価", "数量", "値段"]]

    # テーブルのデータ部
    @order.line_items.map.with_index do |item, i|
      arr << [i+1, item.product_name, item.price, item.quantity, item.total_price]
    end

    # テーブルの合計部
    arr << ["", "", "", "合計", @order.total_price]
    return arr
  end
end

orders_controller.rb

class OrdersController < ApplicationController
  before_action :set_order, only: [:show, :edit, :update, :destroy]

  # GET /orders
  # GET /orders.json
  def index
    @orders = Order.all
  end

  # GET /orders/1
  # GET /orders/1.json
  def show
    respond_to do |format|
      format.html # show.html.erb
      format.pdf do
        # PDF文書を作成

        pdf = Prawn::Document.new
        pdf = OrderPDF.new(@order)

        # フォントを設定(明朝体)
        pdf.font "vendor/fonts/ipaexm.ttf" 


        # 画面にPDFを表示する
        # disposition: "inline" によりPDFはダウンロードではなく画面に表示される
        send_data pdf.render,
          filename:    "#{@order.id}.pdf",
          type:        "application/pdf",
          disposition: "inline"
      end
    end
  end

  # GET /orders/new
  def new
    @order = Order.new
  end

  # GET /orders/1/edit
  def edit
  end

  # POST /orders
  # POST /orders.json
  def create
    @order = Order.new(order_params)

    respond_to do |format|
      if @order.save
        format.html { redirect_to @order, notice: 'Order was successfully created.' }
        format.json { render :show, status: :created, location: @order }
      else
        format.html { render :new }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /orders/1
  # PATCH/PUT /orders/1.json
  def update
    respond_to do |format|
      if @order.update(order_params)
        format.html { redirect_to @order, notice: 'Order was successfully updated.' }
        format.json { render :show, status: :ok, location: @order }
      else
        format.html { render :edit }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /orders/1
  # DELETE /orders/1.json
  def destroy
    @order.destroy
    respond_to do |format|
      format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_order
      @order = Order.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def order_params
      params.require(:order).permit(:purchased_at)
    end
end

show.html.erb

<%- model_class = Order -%>
<div class="page-header">
  <h1><%=t '.title', :default => model_class.model_name.human.titleize %></h1>
</div>

<%# <dl class="dl-horizontal"> %>
<dl class="dl-horizontal">
  <dt><strong>注文番号:</strong></dt>
  <dd><%= @order.id %></dd>
  <dt><strong>注文日:</strong></dt>
  <dd><%= @order.purchased_at %></dd>
</dl>

<table class="table table-striped">
  <thead>
    <tr>
      <th>#</th>
      <th>品名</th>
      <th>単価</th>
      <th>数量</th>
      <th>値段</th>
    </tr>
  </thead>

  <tbody>
    <% @order.line_items.each_with_index do |line_item, idx| %>
      <tr>
        <td><%= idx + 1 %></td>
        <td><%= line_item.product_name %></td>
        <td><%= number_to_currency line_item.price %></td>
        <td><%= line_item.quantity %></td>
        <td><%= number_to_currency line_item.total_price %></td>
      </tr>
    <% end %>  
    <tr class="warning">
      <td colspan="3" />
      <td>合計</td>
      <td><%= number_to_currency @order.total_price %></td>
    </tr>    
  </tbody>
</table>

  <%# <dt><strong><%= model_class.human_attribute_name(:purchased_at) %></strong></dt>
  <%# <dd><%= @order.purchased_at %></dd> 
</dl>

<%= link_to t('.back', :default => t("helpers.links.back")),
              orders_path, :class => 'btn btn-default'  %>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
              edit_order_path(@order), :class => 'btn btn-default' %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
              order_path(@order),
              :method => 'delete',
              :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
              :class => 'btn btn-danger' %>
<%= link_to "PDFで表示",
              order_path(@order, format: "pdf"),
              :class => 'btn btn-primary' %>


よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

以下のサイトで作成したんだと思うのですが、morikawa1さんのコードを確認したところ、initializeの部分で@orderが定義されてませんでした。多分、これが原因だと思います。
https://ruby-rails.hatenadiary.com/entry/20140907/1410078997

def initialize(order)
    super()

    # ここが抜けてました。
    @order = order

    font "vendor/fonts/ipaexm.ttf"
    text "こんにちは, Prawn!! on order_pdf.rb"

    # ヘッダー部分の表示
    header
    # ヘッダーリード部分の表示
    header_lead
    # テーブル部分の表示
    table_content
  end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/27 05:49

    ご回答ありがとうございます。見落としで大変失礼いたしました。助かりました。

    キャンセル

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

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る