導入
Railsアプリケーションにおいて、コントローラー内でデータを条件に応じて取得しセットする際、予期しないバグやデータの不整合が発生することがあります。今回は、特に action_name
を基に条件分岐を行い、会社のデータをセットするケースに焦点を当て、その問題点と解決策を紹介します。
問題の説明
以下のようなコントローラーメソッド set_company
があります。このメソッドは、アクション名に応じて会社の情報を @company
変数にセットする目的で用意されています。
def set_company
@company = case action_name
when 'new'
Company.find(params[:company_id]) if current_customer
current_company if current_company
when 'create'
Company.find(reservation_params[:company_id])
when 'edit', 'update', 'destroy'
@reservation.company
end
end
new
アクションの際に、期待していた @company
が nil
になる問題が発生していました。
原因の分析
問題の原因は、new
アクションのケースで、Company.find(params[:company_id])
の後に current_company
の評価が行われており、Rubyの case
文の特性上、最後に評価された式の結果が @company
にセットされるためです。もし current_company
が nil
または false
を返す場合、@company
も nil
となります。
解決策
この問題を解決するためには、条件分岐を明確にし、確実に params[:company_id]
が存在し、かつ current_customer
が真の場合のみ Company.find(params[:company_id])
を評価するように修正します。
def set_company
@company = case action_name
when 'new'
if current_customer && params[:company_id].present?
Company.find(params[:company_id])
else
current_company
end
when 'create'
Company.find(reservation_params[:company_id])
when 'edit', 'update', 'destroy'
@reservation.company
end
end
結論
この修正により、@company
が正しくセットされるようになり、new
アクションでの期待される動作が保証されます。Railsにおいては、コントローラー内でのデータフローを管理する際には、特に複数の条件が絡む場合には慎重にロジックを設計する必要があります。