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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

1075閲覧

メソッドの分離をしたが、うまく機能しない。 NoMethodError (undefined method `+' for nil:NilClass)

masaosan18

総合スコア64

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/09/26 08:39

編集2020/09/28 07:13

railsでofficesコントローラーのsearchアクションを作成しています。

Ruby

1 def search 2 if params[:city_id] 3 pagy, offices = pagy Office.where(city_id: params[:city_id]) 4 pagy_headers_merge(pagy) 5 elsif params[:keyword] 6 keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) 7 pagy, offices = pagy_array([]) 8 pagy_headers_merge(pagy) 9 search_office_from_keyword(keywords) 10 else 11 pagy, offices = pagy(Office.all) 12 pagy_headers_merge(pagy) 13 end 14 render json: offices, each_serializer: OfficeIndexSerializer, include: '**' 15 end 16 17 def search_office_from_keyword(keywords) 18 keywords.each do |keyword| 19 offices += Office.where('name LIKE (?) OR 20 address LIKE (?) OR 21 near_station LIKE (?) OR 22 introduction LIKE (?) OR 23 company LIKE (?)', 24 "%#{keyword}%", 25 "%#{keyword}%", 26 "%#{keyword}%", 27 "%#{keyword}%", 28 "%#{keyword}%") 29 end 30 end

このアクションが長すぎてRuboCopに怒られてしまったため、メソッドの分離を試みたのですがうまくいきません。

NoMethodError (undefined method `+' for nil:NilClass):

上記のようなエラーが出てしまいます。

条件分岐のelsifの部分で、search_office_from_keyword(keywords)というメソッドを呼び出しています。

解決方法をご存知の方、教えてください。宜しくお願い致します。

### 変更したコード

ruby

1 def search 2 if params[:city_id] 3 pagy, offices = pagy Office.where(city_id: params[:city_id]) 4 elsif params[:keyword] 5 keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) 6 offices = like_(keywords.shift) 7 keywords.each{ |keyword| offices.or(like_keyword) } 8 else 9 pagy, offices = pagy(Office.all) 10 end 11 pagy_headers_merge(pagy) 12 render json: offices, each_serializer: OfficeIndexSerializer, include: '**' 13 end 14 15 def like_(keyword) 16 Office.where('name LIKE ? OR address LIKE ? OR near_station LIKE ? OR introduction LIKE ? OR company LIKE ?',"%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") 17 end

エラー

ruby

1api_1 | Started GET "/offices/search?keyword=%E6%9D%B1%E4%BA%AC" for 172.21.0.1 at 2020-09-28 07:08:29 +0000 2api_1 | Processing by OfficesController#search as */* 3api_1 | Parameters: {"keyword"=>"東京"} 4api_1 | Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms | Allocations: 696) 5api_1 | 6api_1 | 7api_1 | 8api_1 | NoMethodError (undefined method `prev' for nil:NilClass): 9api_1 | 10api_1 | app/controllers/offices_controller.rb:27:in `search'

27行目は

ruby

1 pagy_headers_merge(pagy) 2 render json: offices, each_serializer: OfficeIndexSerializer, include: '**' 3 end

上のコードのpagy_headers_merge(pagy)というコードになります。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2020/09/26 13:30 編集

分離を試したのを載せてください あ、わかりました。
masaosan18

2020/09/26 13:40

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) pagy_headers_merge(pagy) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) pagy, offices = pagy_array([]) pagy_headers_merge(pagy) search_office_from_keyword(offices, keywords) else pagy, offices = pagy(Office.all) pagy_headers_merge(pagy) end render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def search_office_from_keyword(offices, keywords) keywords.each do |keyword| offices += Office.where('name LIKE (?) OR address LIKE (?) OR near_station LIKE (?) OR introduction LIKE (?) OR company LIKE (?)', "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end end
guest

回答1

0

ベストアンサー

elsif params[:keyword]      : offices += search_office_from_keyword(keywords) else def search_office_from_keyword(keywords) keywords.each do |keyword| Office.where(。。。)

としましょう
訂正

def search_office_from_keyword(keywords) offices = [] keywords.each do |keyword| offices += Office.where(。。。) end offices end

でした。
もしくは

def search_office_from_keyword(keywords) keywords.each_with_object([]) do |keyword,offices| offices += Office.where(。。。) end end

追記
pagy は使ったことがないのですが

elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) relation = like_(keywords.shift) keywords.each{ |keyword| relation.or(like_keyword) } pagy, offices = pagy relation else

かな

投稿2020/09/26 13:32

編集2020/09/28 08:01
winterboum

総合スコア23347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaosan18

2020/09/26 13:45

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) pagy_headers_merge(pagy) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) pagy, offices = pagy_array([]) pagy_headers_merge(pagy) offices += search_office_from_keyword(keywords) else pagy, offices = pagy(Office.all) pagy_headers_merge(pagy) end render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def search_office_from_keyword(keywords) keywords.each do |keyword| Office.where('name LIKE (?) OR address LIKE (?) OR near_station LIKE (?) OR introduction LIKE (?) OR company LIKE (?)', "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end end
masaosan18

2020/09/26 13:45

試しましたが、だめでした。。。
winterboum

2020/09/26 13:47

修正版試してください
masaosan18

2020/09/26 13:54

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) pagy_headers_merge(pagy) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) pagy, offices = pagy_array([]) pagy_headers_merge(pagy) offices += search_office_from_keyword(keywords) else pagy, offices = pagy(Office.all) pagy_headers_merge(pagy) end render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def search_office_from_keyword(keywords) offices = [] keywords.each do |keyword| offices += Office.where('name LIKE (?) OR address LIKE (?) OR near_station LIKE (?) OR introduction LIKE (?) OR company LIKE (?)', "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end offices end
masaosan18

2020/09/26 13:54

このような形でしょうか???
masaosan18

2020/09/26 13:57

ページネーション がうまく適用されていないです・・・。
winterboum

2020/09/26 14:04

ああ、効かないですねそれは。ページネーションするなら 一つの式でまとめないと。 結果を足し合わせるのではだめ。
winterboum

2020/09/26 14:05

あれ?検索しきよく見るともしかしたら私が一度回答していない? あの方式にすればpaginationできるんじゃないかな
masaosan18

2020/09/26 14:33

確認してみます。
masaosan18

2020/09/26 15:09

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) pagy_headers_merge(pagy) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) pagy, offices = pagy_array([]) pagy_headers_merge(pagy) search_office_from_keyword(keywords) else pagy, offices = pagy(Office.all) pagy_headers_merge(pagy) end render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def search_office_from_keyword(keywords) offices = [] keywords.each do |keyword| offices += Office.where('name LIKE (?) OR address LIKE (?) OR near_station LIKE (?) OR introduction LIKE (?) OR company LIKE (?)', "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end offices end
masaosan18

2020/09/26 15:10

うまくいきません
winterboum

2020/09/26 21:00

??? どこを変えました? うまくいかないというのはどうなってほしいのにどうなったのですか?
masaosan18

2020/09/27 12:49

headerにページネーションの情報を持たせたいのですが、反映されません。
masaosan18

2020/09/28 05:03

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) offices = like_(keywords.shift) keywords.each{ |keyword| offices.or(like_keyword) } else pagy, offices = pagy(Office.all) end pagy_headers_merge(pagy) render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def like_(keyword) Office.where('name LIKE ? OR address LIKE ? OR near_station LIKE ? OR introduction LIKE ? OR company LIKE ?',"%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end
masaosan18

2020/09/28 05:03

試しましたが。やはりparams[:keyword]のときにうまくいきません。
masaosan18

2020/09/28 05:04

api_1 | Started GET "/offices/search?keyword=%E6%9D%B1%E4%BA%AC" for 172.21.0.1 at 2020-09-28 05:00:41 +0000 api_1 | Processing by OfficesController#search as */* api_1 | Parameters: {"keyword"=>"東京"} api_1 | Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms | Allocations: 709) api_1 | api_1 | api_1 | api_1 | NoMethodError (undefined method `prev' for nil:NilClass): api_1 | api_1 | app/controllers/offices_controller.rb:52:in `search' api_1 | Started GET "/offices/search?keyword=%E6%9D%B1%E4%BA%AC" for 172.21.0.1 at 2020-09-28 05:02:36 +0000 api_1 | Processing by OfficesController#search as */* api_1 | Parameters: {"keyword"=>"東京"} api_1 | Completed 500 Internal Server Error in 14ms (ActiveRecord: 0.0ms | Allocations: 4103) api_1 | api_1 | api_1 | api_1 | NoMethodError (undefined method `prev' for nil:NilClass): api_1 | api_1 | app/controllers/offices_controller.rb:52:in `search'
masaosan18

2020/09/28 05:04

このようなエラーがでてしまう状況です。
winterboum

2020/09/28 06:00

そのエラーがでたcodeを 質問を編集して載せてください・ 及び、52行めがどこか分かるようにしてください
masaosan18

2020/09/28 07:13

ありがとうございます。編集しました。
masaosan18

2020/09/28 08:13

ありがとうございます。 ページネーションはうまく反映しました。
masaosan18

2020/09/28 08:14

api_1 | Started GET "/offices/search?keyword=%E7%A6%8F%E3%80%80%E6%9D%B1%E4%BA%AC" for 172.21.0.1 at 2020-09-28 08:12:21 +0000 api_1 | Processing by OfficesController#search as */* api_1 | Parameters: {"keyword"=>"福 東京"} api_1 | Completed 500 Internal Server Error in 117ms (ActiveRecord: 0.0ms | Allocations: 76584) api_1 | api_1 | api_1 | api_1 | NameError (undefined local variable or method `like_keyword' for #<OfficesController:0x00005576507f97e0> api_1 | Did you mean? keyword): api_1 | api_1 | app/controllers/offices_controller.rb:24:in `block in search' api_1 | app/controllers/offices_controller.rb:24:in `each' api_1 | app/controllers/offices_controller.rb:24:in `search' ただ、複数ワードでの検索をすると上記のようなエラーが出てしまいます。
masaosan18

2020/09/28 08:15

def search if params[:city_id] pagy, offices = pagy Office.where(city_id: params[:city_id]) elsif params[:keyword] keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?) relation = like_(keywords.shift) # offices = like_(keywords.shift) keywords.each{ |keyword| relation.or(like_keyword) } #24行目 pagy, offices = pagy relation else pagy, offices = pagy(Office.all) end pagy_headers_merge(pagy) render json: offices, each_serializer: OfficeIndexSerializer, include: '**' end def like_(keyword) Office.where('name LIKE ? OR address LIKE ? OR near_station LIKE ? OR introduction LIKE ? OR company LIKE ?',"%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%") end
HiroshiUeki

2020/10/05 00:42

> NameError (undefined local variable or method `like_keyword' for #<OfficesController:0x00005576507f97e0> | Did you mean? keyword): となっているので、`like_keyword`が定義されていないのではないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問