「ActiveHashのモデルからnameを取得したいんだけど、undefinedエラーが出て取得できない…」
そんな方向けに、ActiveHashのnameを多少強引に取得する方法と、そもそもnameが取得できない理由について解説していきます。
プログラミング初心者の方は参考にしていただけると幸いです。
(なぜエラーが出るかご存知の方にとっては、この記事は無益です。ごめんなさい。)
この記事の目的
・ActiveHashを使った正常な値の取得方法を復習する
・ActiveHashモデルからfindメソッドで値を取得する方法を学習する
・なぜundefindエラーが発生するのかを理解する
【前提】 ActiveHash 正常な値の取得
class Sushi < ActiveHash::Base
self.data = [
{ id: 1, name: '大トロ' },
{ id: 2, name: '中トロ' },
{ id: 3, name: 'いくら' },
{ id: 4, name: '穴子' },
{ id: 5, name: 'えんがわ' },
{ id: 6, name: '雲丹' },
{ id: 7, name: 'いか' }
]
end
<%= @shari.sushi.name %>
<!-- @shariのsushi_idが「4」 の場合、「穴子」が表示される-->
このような記述で、ActiveHashのモデルから、@shari.sushi_idに紐づくnameの値を取得することができます。(今回モデルの記述は割愛します。)
しかし、__ある条件下__では、ActiveHashのname要素を取得することができず
undefined method '〇〇' for …
のように、エラーとなってしまう場合があります。
そんな時に、無理やりActiveHashのモデルから値を取得する方法をお伝えします。
その①:findを使って取得・表示する
<%= Sushi.find(@shari.neta_id).name %>
「エラーは起きたけど、せっかくActiveHashモデル書いたし使いたいな…」
という方にオススメなのは、__findメソッドを使って無理やり取得__する方法です。
①findメソッドの引数に取得したいidを渡し、Sushiモデル(ActiveHash)から@shari.neta_idを探します。
②取得したidのnameが欲しいため、末尾に.nameをつけてあげます。
③Sushiモデルから、@shari.neta_idに合わせたname要素が取得できます。
多少強引な方法ではありますが、この方法を使えば指定のname要素を取得することができます。ただし、コードが冗長になりやすいので、使うときは注意が必要です。
その②:form.select と Caseで取得・表示する
<%= form.select :neta_id,[["アジ",1],["コハダ",2],["赤むつ",3],["アマダイ",4]] %>
<% case @shari.neta_id %>
<% when 1 then %>
<p>アジ</p>
<% when 2 then %>
<p>コハダ</p>
<% when 3 then %>
<p>赤むつ</p>
<% when 4 then %>
<p>アマダイ</p>
<% end %>
「記述量は少ないし、ActiveHashじゃなくてもいいかな…」
という方は、プルダウン部分をform.selectに、表示部分をcase文で記述することで、擬似的にActiveHashのような表現をすることができます。
ただし、この方法は選択肢が増えると記述量が膨大になり、コードの可読性を下げる可能性があるので、選択肢が少ない場合のみ使用することをオススメします。
そもそもなぜ取得できないの?
結論、__「ActiveHashモデルのモデル名とカラム名が合っていない」__場合、name要素を正規の方法で取得することができません。
カラム名が__sushi_id__(integer型)であった場合、ActiveHashのモデル名も__Sushi.rb__である必要があります。前述その①の場合、Sushi.rbからneta.nameのような形で値を取得しようとしても、取得できません。
ActiveHashモデルを作成してプルダウンやチェックボックスを作る際は、モデルの名前とカラムの名前を揃えるようにしましょう。
まとめ
①ActiveHashはモデル名とカラム名があっていないと、.nameでname要素を取得することができない。
②別名のモデルから値を取得する場合は、findを使うことでname要素を取得することができる。
③記述そのもの(選択肢)が少ない場合は、form.selectとwhenを使うことで表現する方法もある。
最後までご覧いただきありがとうございました。
引き続き、学習を頑張っていきましょう!