0
1

More than 3 years have passed since last update.

【Ruby on Rails】パラメーターのid取得がうまくいかなかった時

Posted at

目標

id情報を取得する。
パラメーター関連でうまくいかないときの解決手順の参考になれば幸いです。

開発環境

ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
google chrome

前提

※ ▶◯◯ を選択すると、説明等が出てきますので、
  よくわからない場合の参考にしていただければと思います。

今回はパラメーターのid取得で躓いてしまったため、
備忘録として記載させていただきます。

状況

  • 投稿機能は実装済み
  • 削除機能の実装を試みる
  • コントローラー、ルーティング、viewそれぞれ記述
  • destroyがnilになる。

これらを解決していきます。

controllerを疑う

app/controllers/img_searchs_controller.rb
  def destroy
    # binding.pry
    @img_searchs = current_customer.img_searchs
    @img_search = @img_searchs.find_by(id: params[:id])
    unless @img_search
      redirect_to new_img_search_path
    end
    if @img_search.destroy
      redirect_to request.referer
    else
      render :new
    end
  end

binding.pryを記述し確認するも、
@img_search = @img_searchs.find_by(id: params[:id])がnilになってしまう。
記述自体は問題なさそうだが、idが渡せていない。
paramsを確認するとid='new'になっている。
(※後述しますがここをしっかり確認できていれば解決は早かったです)
→viewの記述がおかしい可能性あり。

viewを疑う

app/views
<% @img_searchs.each do |img_search| %>

...

<%= link_to "削除", new_img_search_path(img_search), method: :delete %>
<% end %>

each文の中で変数自体も合っており、記述ミスもなさそう。
ただし、今までdestroyメソッドを使ったときには、
img_search_path(img_search), method: :delete
このようにnewがない状態であったため、少し違和感。→ルーティングを確認。

routesを疑う

config/routes.rb
resources :img_searchs, only: [:create, :destroy, :new]

合っている。。。
念の為下記も実行。

ターミナル
$ rails routes
new_img_search GET     /img_searchs/new(.:format)
                public/img_searchs#new
          DELETE  /img_searchs/:id(.:format) 
                        public/img_searchs#destroy

やはり合っている。。。
もう一度viewを確認するもやはり記述自体はあっている。
しかし、画面のカーソルを削除リンクに合わせると。。。
(google chromeでは左下にリンク先のURLが表示されます)

localhost:3000/img_searchs/new.15

/img_searchs/:idの形になっていない!
この時はなぜnewが入るのか全くわかりませんでした。

ただ先程の違和感は解消しておかなければと思い、
あまりきれいな記述ではないものの、ルーティングを書き換えることにしました。

config/routes.rb
resources :img_searchs, only: [:create, :new]
delete 'img_searchs/:id' => 'img_searchs#destroy'

そしてもう一度実行すると

ターミナル
$ rails routes
new_img_search GET     /img_searchs/new(.:format)
                public/img_searchs#new
          DELETE  /img_searchs/:id(.:format) 
                        public/img_searchs#destroy

結果は全く同じでした。
なので、asでパスを指定してみることに。

config/routes.rb
resources :img_searchs, only: [:create, :new]
delete 'img_searchs/:id' => 'img_searchs#destroy', as: 'img_search'

そしてもう一度実行すると下記のようにエラー発生。
内容としては既にそのパス名は使われてますよ。とのこと。

ターミナル
$ rails routes
rails aborted!
ArgumentError: Invalid route name, already in use: 'img_search' 
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here:
...

そんな馬鹿な!と思い調べてみると、
別のページのURLでas: 'img_search'を使っていました。
これが今回の原因です。
そのため下記のようにパス名を変更。

config/routes.rb
resources :img_searchs, only: [:create, :new]
delete 'img_searchs/:id' => 'img_searchs#destroy', as: 'img_search_destroy'

その後、viewのパス名を変更。

app/views
<% @img_searchs.each do |img_search| %>

...

<%= link_to "削除", img_search_destroy_path(img_search), method: :delete %>
<% end %>

正常に動作しました。

まとめ

今回は手早く修正する必要があったため、
既にあったas: 'img_search'を変更するのではなく、
新しく追加した as: 'img_search'を as: 'img_search_destroy'に変更しました。

また今回起こってしまった要因としては、
私自身がroutes.rbの優先順を忘れてしまっていたがために、起こってしまったので、
同じエラーが起きた人の解決の一助になれたら幸いです。

ちなみにroutes.rbの優先順は上に記述したものが優先されます。

エラー解決の方法はいくつもあるため、一歩一歩焦らず蓄えていく必要がありそうです。

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