外部キーのあるモデルのビュー周りで、ActiveRecord::AssociationTypeMismatch errorが発生した。書籍やWebで調べてもぴったり同じ解決法がなかったので、記事として残しておく。
今回実装したかった機能は、外部キーを持つReportsに対してCreate, Read, Updateの機能を実装すること。
難しい実装じゃないはずなんだけど、Railsに慣れていなかったせいか苦労した。これからもっと勉強して実装経験を積んでいかないと、自分のRailsのレベルは実戦には程遠いだろうと感じた。
reports_controller.rb (抜粋)
_form.html.rb
new.html.erb
edit.html.erb
reports_controller.rb (抜粋)
index.html.erb
show.html.erb
今回実装したかった機能は、外部キーを持つReportsに対してCreate, Read, Updateの機能を実装すること。
難しい実装じゃないはずなんだけど、Railsに慣れていなかったせいか苦労した。これからもっと勉強して実装経験を積んでいかないと、自分のRailsのレベルは実戦には程遠いだろうと感じた。
バージョン
- ruby 1.9.3
- rails 3.2.2
データベース定義
ReportsテーブルとSubmittersテーブルがあり、以下のように定義されているとする。テーブル名 | Submitters | |||
---|---|---|---|---|
物理名 | データ型 | Null | Default | 備考 |
id | integer | No | PRIMARY KEY AUTO INCREMENT | |
name | string | Yes | Null | |
created_at | date | No | ||
updated_at | date | No |
テーブル名 | Reports | |||
---|---|---|---|---|
物理名 | データ型 | Null | Default | 備考 |
id | integer | No | PRIMARY KEY AUTO INCREMENT | |
title | string | Yes | Null | |
submitter_id | references | Yes | Null | FOREIGN KEY |
created_at | date | No | ||
updated_at | date | No |
Create & Update
とりあえずコードから。reports_controller.rb (抜粋)
def new @report = Report.new @submitter = Submitter.all respond_to do |format| format.html end end def edit @report = Report.find(params[:id]) @submitter = Submitter.all end def create @report = Report.new(params[:report]) respond_to do |format| if @report.save format.html { redirect_to @report, notice: 'Report was successfully created.' } else format.html { render action: "new" } end end end def update @report = Report.find(params[:id]) respond_to do |format| if @report.update_attributes(params[:report]) format.html { redirect_to @report, notice: 'Report was successfully updated.' } else format.html { render action: "edit" } end end end
_form.html.rb
<%= form_for(@report) do |f| %> <% if @report.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@report.errors.count, "error") %> prohibited this report from being saved:</h2> <ul> <% @report.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :title %><br /> <%= f.text_field :title %> </div> <div class="field"> <%= f.label :submitter %></div> <%= f.collection_select( :submitter_id, @submitter, :id, :name ) %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
new.html.erb
<h1>New report</h1> <%= render 'form' %> <%= link_to 'Back', reports_path %>
edit.html.erb
<h1>Editing report</h1> <%= render 'form' %> <%= link_to 'Show', @report %> | <%= link_to 'Back', reports_path %>
Read
とりあえずコードから。reports_controller.rb (抜粋)
def index @reports = Report.all respond_to do |format| format.html # index.html.erb end end def show @report = Report.find(params[:id]) respond_to do |format| format.html # show.html.erb end end
index.html.erb
<h1>Listing reports</h1> <table> <tr> <th>タイトル</th> <th>提出者</th> <th></th> <th></th> <th></th> </tr> <% @reports.each do |report| %> <tr> <td><%= report.title %></td> <td><%= report.submitter.name if report.submitter %></td> <td><%= link_to 'Show', report %></td> <td><%= link_to 'Edit', edit_report_path(report) %></td> <td><%= link_to 'Destroy', report, confirm: 'Are you sure?', method: :delete %></td> </tr> <% end %> </table> <br /> <%= link_to 'New Report', new_report_path %>
show.html.erb
<p id="notice"><%= notice %></p> <p> <b>Title:</b> <%= @report.title %> </p> <p> <b>Submitter:</b> <%= @report.submitter.name %> </p> <%= link_to 'Edit', edit_report_path(@report) %> | <%= link_to 'Back', reports_path %>