LoginSignup
0
0

More than 3 years have passed since last update.

ActiveHashを導入した際のselectメソッドの使用方法

Posted at

環境

'rails', '~> 6.0.0'

'capybara', '>= 2.15'

ruby '2.6.5'

はじめに

systemspecによる結合テストを行なっている際に、トップページレンダーした時に、以下のようなエラーが発生しました。
結論からお話しますと、このエラーはCapybaraのselectメソッドの記述ミスにより発生するものでした。
以下、エラーが発生した記述ではselectメソッドで’法規・条例’という文字をcategoryから探して選択するという記述をしているのですが、
実際の挙動としてはそこで選択した項目のidを引数として、トップページに渡すという作業をしています。

undefined method `[]' for nil:NilClass

とはselectメソッドで指定すべきidがありませんという内容と想定されます。
そのため、selectメソッドの中に引数となるidの番号を含めて記述しなくてはなりません。

エラーの原因となったコードを見てみますと、

select '法規・条例', from: 'tip_category_id'

となっておりますが、これをidを含めた形に修正すると、以下のようになります。

select Category.data[@tip.category_id - 1][:name], from: 'tip_category_id

Categoryモデルから@tipを引数にidを選択する記述に変更しました。
なお、activeHashは0から始まる番号で数字を選択するため、idとの関連性を考慮し、category_id -1 をしております。

以下、記述内容

エラー本文

Failure/Error: <p class="tiped-title-contents">カテゴリー :  <%= Category.data[f.category_id][:name] %></p>

     ActionView::Template::Error:
       undefined method `[]' for nil:NilClass

     [Screenshot]: /Users/taniguroarata/originalapp/archtips/tmp/screenshots/failures_r_spec_example_groups_nested_nested_visit_new_user_session_path_231.png


     # ./app/views/tips/_main_area.html.erb:17:in `block in _app_views_tips__main_area_html_erb__1894181271776908624_70358077282820'
     # ./app/views/tips/_main_area.html.erb:12:in `_app_views_tips__main_area_html_erb__1894181271776908624_70358077282820'
     # ./app/views/tips/index.html.erb:10:in `_app_views_tips_index_html_erb___4391342711310590138_70357992921920'
     # ------------------
     # --- Caused by: ---
     # NoMethodError:
     #   undefined method `[]' for nil:NilClass
     #   ./app/views/tips/_main_area.html.erb:17:in `block in _app_views_tips__main_area_html_erb__1894181271776908624_70358077282820'

spec/system/tips_spec.rb

require 'rails_helper'

RSpec.describe "投稿する", type: :system do
  before do
    @tip =  FactoryBot.create(:tip)
    @user = FactoryBot.create(:user)
  end

  context '投稿に成功した時' do
    it 'visit new_user_session_path' do
      visit new_user_session_path
      fill_in 'user_email', with: @user.email
      fill_in 'user_password', with: @user.password
      find('input[type="submit"]').click
      expect(current_path).to eq(root_path)
      expect(page).to have_content('新規投稿')
      visit new_tip_path
      fill_in 'tip_title', with: @tip.title

      select '法規・条例', from: 'tip_category_id' #ここがエラーの原因です
      #以下のように修正します
      select Category.data[@tip.category_id - 1][:name], from: 'tip_category_id

      fill_in 'tip_description', with: @tip.description
      binding.pry
      expect{
        find('input[type="submit"]').click
      }.to change {Tip.count }.by(1)
      expect(current_path).to eq(root_path)
    end
  end
end

app/views/tips/new.html.erb (テスト時の画面)

※画像の投稿は必須ではないため、今回は飛ばしてテストしております

<div class = "wrapper">
  <%= render "shared/header" %>
  <div class="main-tips-new">
    <div class = "new-tip-string">
      <p>新規投稿</p>
    </div>
    <%= form_with(model: @tip, local: true) do |form| %>
      <%= render 'layouts/error_messages', model: form.object, class:"" %>
      <div class="tip-title">
        <p>タイトル</p>
        <div class="tip-title-content">
          <%= form.text_field :title, placeholder: "" %>
        </div>
      </div>
      <div class="tip-category">
        <p>カテゴリー</p>
        <div class="tip-category-content">
          <%= form.collection_select(:category_id, Category.all, :id, :name, {}, {class:""}) %> #ここにactiveHashを用いて、番号によって項目を、選択をしております。
        </div>
      </div>
      <div class="tip-images">
        <div class="tip-image-main">
          <p class="tip-image-main-text">画像(メイン)</p>
          <div id="image-list">
            <%= form.file_field :image, class: 'tip-image-main-img' %>
          </div>
        </div>
        <div class="tip-image-sub">
          <p class="tip-image-sub-text">画像(サブ)</p>
          <div class="tip-image-sub-images">
            <%= form.file_field :image, class: 'tip-image-sub-img' %>
            <%= form.file_field :image, class: 'tip-image-sub-img' %>
            <%= form.file_field :image, class: 'tip-image-sub-img' %>
          </div>
        </div>
      </div>
      <div class="tip-description">
        <p class="tip-description-text">説明</p>
        <%= form.text_field :description, placeholder:"", class: 'text-form' %>
      </div>
      <%= form.submit "投稿する" %>
    <% end %>
  </div>
</div>

app/models/category.rb

class Category < ActiveHash::Base
  self.data = [
    { id: 1, name: '--' },
    { id: 2, name: '法規・条例' },
    { id: 3, name: '納まり・詳細図' },
    { id: 4, name: '仕上げ' },
  ]

  include ActiveHash::Associations
  has_many :categories

  end

終わりに

select等の要素を選択する際にはbinding.pryで値を確認しつつ行うとうまくいくことが多いです。
この記事が皆様のお役に立てればとおもいます。

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