5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ざっくり解説】ActiveHashモデルからnameが取得できない原因と対処法

Last updated at Posted at 2020-10-12

「ActiveHashのモデルからnameを取得したいんだけど、undefinedエラーが出て取得できない…」

そんな方向けに、ActiveHashのnameを多少強引に取得する方法と、そもそもnameが取得できない理由について解説していきます。

プログラミング初心者の方は参考にしていただけると幸いです。
(なぜエラーが出るかご存知の方にとっては、この記事は無益です。ごめんなさい。)

この記事の目的

・ActiveHashを使った正常な値の取得方法を復習する
・ActiveHashモデルからfindメソッドで値を取得する方法を学習する
・なぜundefindエラーが発生するのかを理解する

【前提】 ActiveHash 正常な値の取得

sushi.rb
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
lunch.html.erb
<%= @shari.sushi.name %>
<!-- @shariのsushi_idが「4」 の場合、「穴子」が表示される-->

このような記述で、ActiveHashのモデルから、@shari.sushi_idに紐づくnameの値を取得することができます。(今回モデルの記述は割愛します。)

しかし、__ある条件下__では、ActiveHashのname要素を取得することができず

undefined method '〇〇' for …

のように、エラーとなってしまう場合があります。

そんな時に、無理やりActiveHashのモデルから値を取得する方法をお伝えします。

その①:findを使って取得・表示する

lunch.html.erb
<%= 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で取得・表示する

new.html.erb
<%= form.select :neta_id,[["アジ",1],["コハダ",2],["赤むつ",3],["アマダイ",4]] %>
lunch.html.erb
<% 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を使うことで表現する方法もある。

最後までご覧いただきありがとうございました。
引き続き、学習を頑張っていきましょう!

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?