RailsのView内でSomeTable.allはありなのか

やりたいこと

  • View内で、selectタグの中身(option)に別のテーブルの内容を表示する。

コード

# 一回ごとの支払い(expense)用のコントローラ
# app/controllers/expenses_controller.rb
  # GET /expenses/new
  # GET /expenses/new.xml
class ExpensesController < ApplicationController
  # ...
  def new
    @expense = Expense.new
    @categories = Category.all

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @expense }
    end
  end

#------------------------------------------------------------

# Expense の View
# app/views/expenses/_form.html.erb
  # ...
  <div class="field">
    <%= expense_form.label :category %><br />
    <%= expense_form.select :category_id, @categories.map { |c| [ c.name, c.id ] } %>
  </div>
  # ...

これでとりあえず動く。

問題点

問題は、validationが失敗した時に@categoriesがnilになっていてエラーになる事。

 NoMethodError in Expenses#create

Showing /Users/naoto/gh/heroku/money/app/views/expenses/_form.html.erb where line #29 raised:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.map

解決するには単純にView内で Category.all.map... とすればとりあえず動く。

↑これがやりたい

で、動くは動くんだけど、View内でModelを直接呼ぶのってありなのかなぁというのが疑問。
今のところは動けばいいのでこれでいいことにしてる。