2011年1月20日木曜日

Rails:簡易辞書システムを作成しよう2

今回想定しているエンティティは
  • ドメイン
  • 辞書
2つです。
辞書の名称(論理名)と物理名にはとりあえず一意制約を付けておきます。
class Dictionary < ActiveRecord::Base
  validates_uniqueness_of :logical_name
  validates_uniqueness_of :physical_name
end


次に、1つのドメインに対し、辞書の項目が複数対応する一対多の関係を持ちますので、その関連をModelに設定します。

#辞書
class Dictionary < ActiveRecord::Base
  belongs_to :domain
  
  validates_uniqueness_of :logical_name
  validates_uniqueness_of :physical_name
end

#ドメイン
class Domain < ActiveRecord::Base
  has_many :dictionaries
end
辞書にはドメイン1つが設定されます。
また、ドメインは複数の辞書項目が対応します。

 belongs_to :domain

のシンボル:domainは単数形ですが、

 has_many :dictionaries

の辞書は複数レコードとなるため、複数形のシンボル:dictionariesを指定します。

続いてViewを修正します。・・・がここでハマってしまいました。
WebでRailsのドキュメントhttp://api.rubyonrails.org/を参照していたのですが、Rails 3.0.3(当時)だったのです。
collection_selectメソッドの引数がどうもRails 2.3.xと異なっているようですね。

ドキュメントを見ながらnew.html.erb修正すると、以下のような感じ・・・

<p>
    <%= f.label :domain_id %><br />
    <%= collection_select(:dictionary, :domain_id, Domain.all, :id, :domain_name, :prompt => true) %>
  </p>


サーバログを見ると、プルダウンから値が取得できていない・・・。登録処理でNULLがインサートされてしまいました。

[4;36;1mSQL (0.0ms) [0m    [0;1mINSERT INTO `dictionaries` (`logical_name`, `physical_name`, `domain_id`, `data_type`, `data_digit`, `remark`, `created_at`, `updated_at`) VALUES('aaa', 'a', NULL, 'string', '', 'aaa', '2011-01-20 11:40:10', '2011-01-20 11:40:10') [0m

次に
f.collection_select(.....

に修正したら今度は

undefined method `merge' for :domain_name:Symbol

しばらく考え、Railsレシピブックを見直したところ、出ていました。引数が違う・・・
実は第1引数の :dictionary が不要でした。

<p>
    <%= f.label :domain_id %><br />
    <%= f.collection_select(:domain_id, Domain.all, :id, :domain_name, :prompt => true) %>

が正解だったようです。

テーブルの正規化など、他のテーブル(Model)の値をプルダウンで表示させたいことは多々あると思います。
頻繁に利用する機会も出てくるでしょう。

0 件のコメント:

コメントを投稿