LoginSignup
1
0

More than 1 year has passed since last update.

【Rails】ActiveHashでcollection_selectしたのにプルダウンが表示されないエラー

Posted at

この記事ではRails 6.0.0を使用しております。

当方、プログラミング初学者です。
Ruby on Railsにおいて、ActiveHashの学習中に発生したエラーについて
備忘録として残したいと思います。

結論から言うと、単なるスペルミスが原因のエラーでしたが、
エラー表示がパッとでてこなかった場合の、エラーの原因を探す1つの方法を記します。

ActiveHashの学習のために、簡易的な記事投稿アプリを作成しております。
記事の"ジャンル"をActiveHashで表示させるようにします。
ActiveHashの導入方法などは、他の記事を参照してもらうとして、
gem導入後、下記のようにモデル、コントローラー、ビューを作成しました。

app/models/genre.rb
class Genre < ActiveHash::Base
  self.date = [
    { id: 1, name: '--' },
    { id: 2, name: '経済' },
    { id: 3, name: '政治' },
    { id: 4, name: '地域' },
    { id: 5, name: '国際' },
    { id: 6, name: 'IT' },
    { id: 7, name: 'エンタメ' },
    { id: 8, name: 'スポーツ' },
    { id: 9, name: 'グルメ' },
    { id: 10, name: 'その他' }
  ]

  include ActiveHash::Associations
  has_many :articles

end
app/models/article.rb
class Article < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre

  validates :title, :text, presence: true
  validates :genre_id, numericality: { other_than: 1 , message: "can't be blank"}
end
articles_controller.rb
class ArticlesController < ApplicationController
  def index
    @articles = Article.order("created_at DESC")
  end

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def article_params
    params.require(:article).permit(:title, :text, :genre_id)
  end

end
views/articles/new.html.erb
<%= form_with model: @article, url:articles_path, local: true do |f| %>
  <div class="article-box">
    記事を投稿する
    <%= f.text_field :title, class:"title", placeholder:"タイトル" %>
    <%= f.text_area :text, class:"text", placeholder:"テキスト" %>
    <%= f.collection_select(:genre_id, Genre.all, :id, :name, {}, {class:"genre-select"}) %>
    <%= f.submit "投稿する" ,class:"btn" %>
  </div>
<% end %>
routes.rb
Rails.application.routes.draw do
  get 'articles/index'
  get 'articles/new'
  root to: 'articles#index'
  resources :articles
end

いざブラウザにて動作確認しようとしたら、
なぜかActiveHashのフォームが空になっており、クリックしてもプルダウンを表示できない…。
上記の通り、バリデーションにて初期値で '--' を表示させる設定にしているのに、それすらも表示されない…。
明らかにおかしいのにエラー文でないし、ヒントになるものがない!
とパニックに陥りかけましたが、まずは状況を整理し、以下の仮説を立てました。

  1. ビューのform_with以下の記述に間違っている部分がある。
  2. 空欄になっているということは、genreモデルから情報を取得できていない。

まず、1つ目の仮説を検証します。
ビューを念入りにチェックしますが、スペルなどを間違っている部分は見当たらない…。
次に2つ目の仮説検証のために、他のルーティングや設定したバリデーションやアソシエーションが間違ってないかを確認しますが、
間違っていそうな部分がこの時点では見つけられませんでした…。
もう先人のお知恵を借りるしかないと、ググってみたところ、
こちらの記事( Pikawaka )の中のこの一文に目が止まりました。

試しにコンソールモードでactive_hashのallメソッドを使ってみましょう。
〜中略〜
このようにデータベースに登録してある時と同じ挙動になるのが確認できました。

なるほど。コンソールでデータベースから情報を取得できているか確認すればいいのか!
ということで早速実行してみると一発で原因がわかりました。

% rails c

irb(main):001:0> Genre.all
Traceback (most recent call last):
        3: from (irb):1
        2: from app/models/genre.rb:1:in `<main>'
        1: from app/models/genre.rb:2:in `<class:Genre>'
NoMethodError (undefined method `date=' for Genre:Class)
Did you mean?  data=
               data
irb(main):002:0>

このように、genreモデルのメソッドが違う気がするよ!
と教えてくれました。
下記のように修正したら、ちゃんと意図した通りにプルダウンできるようになりました。

genre.rb
class Genre < ActiveHash::Base
  self.data = [
    { id: 1, name: '--' },
    { id: 2, name: '経済' },
  # 以下省略

単純なミスほど見落としがちですので、意図しない挙動をしても
落ち着いて対処できるようになりたいものです。
しかし、'data'と'date'はどうやって使い分けるのだろうか…。
これはまた今度調べようと思います。

1
0
1

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
1
0