質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.22%

多階層カテゴリーを実現したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 267

unchan_net

score 3

Railsで多階層カテゴリーを実装したいと思っております。

都道府県を選択すると、それと関連性のある市区町村が表示される機能です。
(例:茨城県 => つくば市)

自分で一から制作するほどのスキルはないため、下記URLを参考にしながら実装を進めていたところ躓きました。

http://kawahiro.hatenablog.jp/entry/2013/10/26/233051

出ているエラーとしましては、「ArgumentError」で、

<%= collection_select :city_id, City.where(prefecture_id: prefecture_id), :id, :name %>

恐らく、こちらの記述の部分がおかしいと思うのですが、原因がわかりません。

念の為、関係のありそうな周辺ファイルも添付しておきます。

[ _cities.html.erb ]

<div class="field">
<%= collection_select :city_id, City.where(prefecture_id: prefecture_id), :id, :name %>
</div>


[routers.rb]

~省略
  resources :microposts,          only: [:create, :destroy]
  resources :microposts do
    collection do
      get :cities_select
    end
  end
end

[ _micropost_form.html.erb ]

<%= form_for(@micropost) do |f| %>
    <%= render 'shared/error_messages', object: f.object %>
    <div class="field">
      <%= f.text_area :content, placeholder: "Compose new micropost..." %>
    </div>
    <div class="field">
    <%= f.label :prefecture_id,"都道府県" %>
    <%= f.collection_select :prefecture_id, Prefecture.all, :id, :name, include_blank: "選択してください" %>
    </div>
    <div class="field">
    <%= f.label :city_id,"市区町村" %>
    <%= render partial: 'cities', locals: {prefecture_id: Prefecture.first.id} %>
    </div>
    <%= f.submit "Post", class: "btn btn-primary" %>
<% end %>


[ micropost.rb ]

class Micropost < ApplicationRecord
  belongs_to :user
  belongs_to :prefecture, optional: true
  belongs_to :city 
  default_scope -> { order(created_at: :desc) }
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 1000 }
end


[schema.rb]

ActiveRecord::Schema.define(version: 2020_08_29_105438) do

  create_table "cities", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.integer "prefecture_id"
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "microposts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.text "content"
    t.bigint "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "prefecture_id"
    t.index ["prefecture_id"], name: "index_microposts_on_prefecture_id"
    t.index ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at"
    t.index ["user_id"], name: "index_microposts_on_user_id"
  end

  create_table "prefectures", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string "current_sign_in_ip"
    t.string "last_sign_in_ip"
    t.string "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.string "unconfirmed_email"
    t.integer "failed_attempts", default: 0, null: false
    t.string "unlock_token"
    t.datetime "locked_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "provider"
    t.string "uid"
    t.string "username"
    t.string "image"
    t.text "profile"
    t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true
  end

  add_foreign_key "microposts", "prefectures"
  add_foreign_key "microposts", "users"
end


[micropost.coffee]

$(document).on 'change', '#company_ms_pref', ->
  $.ajax(
    type: 'GET'
    url: '/microposts/cities_select'
    data: {
      ms_pref_id: $(this).val()
    }
  ).done (data) ->
    $('#cities_select').html(data)


[microposts_controller.rb]

~省略
def cities_select
      if request.xhr?
        render partial: 'cities', locals: {prefecture_id: params[:prefecture_id]}
      end
    end

ただ、どこを間違えているのかの見当がつかないあたり、自身のスキルが不足していることも重々承知しております。

ですので、エラーの解決法ではなく、「〜あたりがおかしい、〇〇についてもっと勉強すればわかる」等、抽象的なアドバイスでも、とても嬉しいです。

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • no1knows

    2020/08/30 20:50

    エラーの内容はすべて正確に記載してください。

    キャンセル

  • unchan_net

    2020/08/30 21:03

    申し訳ありません。

    ArgumentError in StaticPages#home

    Showing /app_name/app/views/static_pages/_cities.html.erb where line #2 raised:

    wrong number of arguments (given 4, expected 5..7)
    Extracted source (around line #2):
    1
    2
    3

    <div class="field">
    <%= collection_select :city_id, City.where(prefecture_id: prefecture_id), :id, :name %>
    </div>

    Trace of template inclusion: app/views/shared/_micropost_form.html.erb, app/views/static_pages/home.html.erb

    Rails.root: /app_name

    Application Trace | Framework Trace | Full Trace
    app/views/static_pages/_cities.html.erb:2:in `_app_views_static_pages__cities_html_erb___1302765098415965002_69977113784340'
    app/views/shared/_micropost_form.html.erb:12:in `block in _app_views_shared__micropost_form_html_erb___54028724847143868_69977114408500'
    app/views/shared/_micropost_form.html.erb:1:in `_app_views_shared__micropost_form_html_erb___54028724847143868_69977114408500'
    app/views/static_pages/home.html.erb:8:in `_app_views_static_pages_home_html_erb__1402849096658922661_69977114476620'
    Request

    こちらになります。

    よろしくお願いします。

    キャンセル

  • no1knows

    2020/08/30 21:16

    こちらが参考になるかもしれません。ならなかったらすいません。
    https://teratail.com/questions/14444

    キャンセル

  • unchan_net

    2020/08/31 07:08

    ありがとうございます。
    こちらのページは見た事がなかったので、とても参考になりました。

    キャンセル

回答 2

checkベストアンサー

0

ここのエラー分で_cities.html.erbの2行目のエラーとわかります。
エラー内容は、引数に4つ与えているが、必要(=期待)しているのは5~7個の引数という点です。

Showing /app_name/app/views/static_pages/_cities.html.erb where line #2 raised:

wrong number of arguments (given 4, expected 5..7)

エラーが起きている場所はここです。

<%= collection_select :city_id, City.where(prefecture_id: prefecture_id), :id, :name %>

https://railsdoc.com/page/collection_select
ここにcollection_selectの使い方がかかれています。
ドキュメントに書いてあるように、引数の数を5個にしたのが以下です。

<%= collection_select :city_id, :name, City.where(prefecture_id: prefecture_id), :id, :name %>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/31 17:08

    ありがとうございます。
    言われた通りに変更したところ、できました!

    キャンセル

  • 2020/08/31 17:10

    また、エラーの見方までご教授していただき、誠にありがとうございます。
    別の方の回答でも解決できたのですが、hatsuさんの方が早かったのと、少し詳しく書かれていたのでベストアンサーにさせて頂きました。
    本当にありがとうございました。

    キャンセル

0

collection_select は 同名のmethodが2種あります。
ひとつは 引数が 4〜6、 f.collection_select
一つが 5〜7のものです。collection_select
unchan_net さんの _cities での使い方が 後者になっているのがエラーの原因です。

<%= render partial: 'cities', のlocals に f: f を加え
<%= f.collection_select :city_id,。。。 にしてください

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/31 17:07

    ありがとうございます!解決できました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る