質問編集履歴
4
「最終的に解決したコード」を追記致しました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -475,3 +475,55 @@
|
|
475
475
|
例えば上記の条件で検索した場合:
|
476
476
|
|
477
477
|
男性で、かつ日本語・中国語をともに話せ(それ以上話せても可)、かつ自己紹介欄に「hoge」の文言を含むユーザーをヒットさせたいです(名前は問わない。[]と言う名前と言う訳ではない)。
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
### 最終的に解決したコード
|
482
|
+
|
483
|
+
|
484
|
+
|
485
|
+
**users_controller.rb**
|
486
|
+
|
487
|
+
```ruby
|
488
|
+
|
489
|
+
@users = User.all.order(created_at: :desc).page(params[:page]).per(20)
|
490
|
+
|
491
|
+
|
492
|
+
|
493
|
+
if params[:language_ids].present?
|
494
|
+
|
495
|
+
@users = @users.select("users.*, COUNT(*) AS languages_count")
|
496
|
+
|
497
|
+
.joins(:user_languages)
|
498
|
+
|
499
|
+
.where(user_languages: { language_id: params[:language_ids] })
|
500
|
+
|
501
|
+
.group("user_languages.user_id")
|
502
|
+
|
503
|
+
.having("languages_count = #{params[:language_ids]&.length}")
|
504
|
+
|
505
|
+
end
|
506
|
+
|
507
|
+
|
508
|
+
|
509
|
+
if params[:name].present? || params[:gender].present? || params[:introduction].present?
|
510
|
+
|
511
|
+
@users = @users.where(['name LIKE ? AND gender LIKE ? AND introduction LIKE ?',
|
512
|
+
|
513
|
+
"%#{params[:name]}%", "#{params[:gender]}%", "%#{params[:introduction]}%"])
|
514
|
+
|
515
|
+
end
|
516
|
+
|
517
|
+
|
518
|
+
|
519
|
+
if @users == []
|
520
|
+
|
521
|
+
# 該当のユーザーが存在しなかった場合。
|
522
|
+
|
523
|
+
flash[:notice] = "User was not found"
|
524
|
+
|
525
|
+
@users
|
526
|
+
|
527
|
+
end
|
528
|
+
|
529
|
+
```
|
3
検索の仕様に関して、追記2を書き加えました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -415,3 +415,63 @@
|
|
415
415
|
Completed 200 OK in 342ms (Views: 304.0ms | ActiveRecord: 5.3ms)
|
416
416
|
|
417
417
|
```
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
### 追記2
|
422
|
+
|
423
|
+
|
424
|
+
|
425
|
+
【検索の仕様に関して】
|
426
|
+
|
427
|
+
仕様と致しましては、検索された言語(複数可)を「全てを含んだ」ユーザーをヒットさせたいです。
|
428
|
+
|
429
|
+
|
430
|
+
|
431
|
+
- ユーザーA: 日本語
|
432
|
+
|
433
|
+
- ユーザーB: 日本語、英語
|
434
|
+
|
435
|
+
- ユーザーC: 日本語、英語、中国語
|
436
|
+
|
437
|
+
|
438
|
+
|
439
|
+
例えば上記のユーザーがいた場合、
|
440
|
+
|
441
|
+
①「日本語」で検索 → A, B, C全員をヒットさせたい。
|
442
|
+
|
443
|
+
②「日本語、英語」で検索 → B, Cをヒットさせたい。
|
444
|
+
|
445
|
+
③「英語、中国語」で検索 → Cのみをヒットさせたい。
|
446
|
+
|
447
|
+
|
448
|
+
|
449
|
+
※完全一致ではない。
|
450
|
+
|
451
|
+
「日本語」でユーザー検索 → 完全一致ですと「日本語のみ」を話せるユーザーAだけがヒットすると思いますが、実装したいのはこちらの機能ではありません。
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
※部分一致でもない。
|
456
|
+
|
457
|
+
「日本語、英語」でユーザー検索 → 部分一致ですと「日本語または英語のどちらか」を話せるユーザーA, B, Cの全てがヒットすると思いますが、実装したいのはこちらの機能でもありません。
|
458
|
+
|
459
|
+
|
460
|
+
|
461
|
+
名前や性別を含んだ検索でも同様に、検索された文言を「全て含んだ」ユーザーをヒットさせたいです。
|
462
|
+
|
463
|
+
|
464
|
+
|
465
|
+
- 名前:(指定なし)
|
466
|
+
|
467
|
+
- 性別:Male
|
468
|
+
|
469
|
+
- 言語:日本語、中国語
|
470
|
+
|
471
|
+
- キーワード:hoge
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
例えば上記の条件で検索した場合:
|
476
|
+
|
477
|
+
男性で、かつ日本語・中国語をともに話せ(それ以上話せても可)、かつ自己紹介欄に「hoge」の文言を含むユーザーをヒットさせたいです(名前は問わない。[]と言う名前と言う訳ではない)。
|
2
【追記】から下を書き加えました。また sex の部分は gender に置き換えました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -52,9 +52,9 @@
|
|
52
52
|
|
53
53
|
<p>Gender</p>
|
54
54
|
|
55
|
-
<%= f.radio_button :
|
55
|
+
<%= f.radio_button :gender, "Male", :checked => params[:gender] == ("Male") %>Male
|
56
|
-
|
56
|
+
|
57
|
-
<%= f.radio_button :
|
57
|
+
<%= f.radio_button :gender, "Female", :checked => params[:gender] == ("Female") %>Female
|
58
58
|
|
59
59
|
|
60
60
|
|
@@ -76,17 +76,17 @@
|
|
76
76
|
|
77
77
|
|
78
78
|
|
79
|
-
**users_
|
79
|
+
**users_controller.rb**
|
80
80
|
|
81
81
|
```ここに言語名を入力
|
82
82
|
|
83
83
|
def index
|
84
84
|
|
85
|
-
if params[:name].present? || params[:introduction].present? || params[:
|
85
|
+
if params[:name].present? || params[:introduction].present? || params[:gender].present? || params[:language_ids].present?
|
86
|
-
|
86
|
+
|
87
|
-
@users = User.where(['name LIKE ? AND introduction LIKE ? AND
|
87
|
+
@users = User.where(['name LIKE ? AND introduction LIKE ? AND gender LIKE ? AND language LIKE ?',
|
88
|
-
|
88
|
+
|
89
|
-
"%#{params[:name]}%", "%#{params[:introduction]}%", "#{params[:
|
89
|
+
"%#{params[:name]}%", "%#{params[:introduction]}%", "#{params[:gender]}%", "%#{params[:language_ids]}%"])
|
90
90
|
|
91
91
|
.page(params[:page]).per(20)
|
92
92
|
|
@@ -181,3 +181,237 @@
|
|
181
181
|
RubyGems 3.0.3
|
182
182
|
|
183
183
|
Rails 5.2.3
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
### 【追記】
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
#### モデル関連
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
**user.rb**
|
196
|
+
|
197
|
+
```
|
198
|
+
|
199
|
+
class User < ApplicationRecord
|
200
|
+
|
201
|
+
has_many :user_languages, dependent: :destroy
|
202
|
+
|
203
|
+
has_many :languages, through: :user_languages
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
```
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
**language.rb**
|
212
|
+
|
213
|
+
```
|
214
|
+
|
215
|
+
class Language < ApplicationRecord
|
216
|
+
|
217
|
+
has_many :user_language
|
218
|
+
|
219
|
+
has_many :users, through: :user_language
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
```
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
**user_language.rb**
|
228
|
+
|
229
|
+
```
|
230
|
+
|
231
|
+
class UserLanguage < ApplicationRecord
|
232
|
+
|
233
|
+
belongs_to :user
|
234
|
+
|
235
|
+
belongs_to :language
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
```
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
#### テーブル情報
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
**schema.rb**
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
|
251
|
+
ActiveRecord::Schema.define(version: 2021_03_11_063016) do
|
252
|
+
|
253
|
+
create_table "languages", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
254
|
+
|
255
|
+
t.string "description"
|
256
|
+
|
257
|
+
t.boolean "done"
|
258
|
+
|
259
|
+
t.bigint "user_id"
|
260
|
+
|
261
|
+
t.datetime "created_at", null: false
|
262
|
+
|
263
|
+
t.datetime "updated_at", null: false
|
264
|
+
|
265
|
+
t.index ["user_id"], name: "index_languages_on_user_id"
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
|
271
|
+
create_table "user_languages", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
272
|
+
|
273
|
+
t.bigint "user_id"
|
274
|
+
|
275
|
+
t.bigint "language_id"
|
276
|
+
|
277
|
+
t.datetime "created_at", null: false
|
278
|
+
|
279
|
+
t.datetime "updated_at", null: false
|
280
|
+
|
281
|
+
t.index ["language_id", "user_id"], name: "index_user_languages_on_language_id_and_user_id", unique: true
|
282
|
+
|
283
|
+
t.index ["language_id"], name: "index_user_languages_on_language_id"
|
284
|
+
|
285
|
+
t.index ["user_id"], name: "index_user_languages_on_user_id"
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
|
292
|
+
|
293
|
+
t.string "name"
|
294
|
+
|
295
|
+
t.datetime "created_at", null: false
|
296
|
+
|
297
|
+
t.datetime "updated_at", null: false
|
298
|
+
|
299
|
+
t.string "gender" # "sex" から "gender" に変更しました。
|
300
|
+
|
301
|
+
t.string "language"
|
302
|
+
|
303
|
+
t.text "introduction"
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
add_foreign_key "languages", "users"
|
310
|
+
|
311
|
+
add_foreign_key "user_languages", "languages"
|
312
|
+
|
313
|
+
add_foreign_key "user_languages", "users"
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
```
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
#### ログ関連
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
以下の言語を話せるユーザーに関する `language` 情報を確認したログを追記致しました。
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
- ユーザーA(`id: 1`): 日本語
|
330
|
+
|
331
|
+
- ユーザーB(`id: 2`): 日本語、英語
|
332
|
+
|
333
|
+
- ユーザーC(`id: 3`): 日本語、英語、中国語
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
```
|
338
|
+
|
339
|
+
[36] pry(main)> User.find(1).language
|
340
|
+
|
341
|
+
User Load (33.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
|
342
|
+
|
343
|
+
=> "[\"1\"]"
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
[37] pry(main)> User.find(2).language
|
348
|
+
|
349
|
+
User Load (1.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
|
350
|
+
|
351
|
+
=> "[\"1\", \"2\"]"
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
[38] pry(main)> User.find(3).language
|
356
|
+
|
357
|
+
User Load (20.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
|
358
|
+
|
359
|
+
=> "[\"1\", \"2\", \"3\"]"
|
360
|
+
|
361
|
+
```
|
362
|
+
|
363
|
+
`/` (コマンド上では `¥`) が表示されていました。ここに問題があったのでしょうか…。
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
#### winterboumさまにご提示頂いたコードで検索した際のログ
|
368
|
+
|
369
|
+
|
370
|
+
|
371
|
+
以下のユーザーしか存在しない中で「英語」のみで検索した所、誰もヒットしませんでした。
|
372
|
+
|
373
|
+
|
374
|
+
|
375
|
+
- ユーザーA(`id: 1`): 日本語
|
376
|
+
|
377
|
+
- ユーザーB(`id: 2`): 日本語、英語
|
378
|
+
|
379
|
+
- ユーザーC(`id: 3`): 日本語、英語、中国語
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
```
|
384
|
+
|
385
|
+
Parameters: {"utf8"=>"✓", "name"=>"", "language_ids"=>["2], "introduction"=>"", "commit"=>"search"}
|
386
|
+
|
387
|
+
User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
|
388
|
+
|
389
|
+
↳ app/controllers/application_controller.rb:9
|
390
|
+
|
391
|
+
User Load (0.8ms) SELECT `users`.* FROM `users` WHERE (name LIKE '%%' AND introduction LIKE '%%' AND gender LIKE '%') AND `users`.`language` = '2' LIMIT 20 OFFSET 0
|
392
|
+
|
393
|
+
↳ app/controllers/users_controller.rb:34
|
394
|
+
|
395
|
+
Rendering users/index.html.erb within layouts/application
|
396
|
+
|
397
|
+
User Load (2.4ms) SELECT `users`.* FROM `users` ORDER BY `users`.`created_at` DESC LIMIT 20 OFFSET 0
|
398
|
+
|
399
|
+
↳ app/views/users/index.html.erb:40
|
400
|
+
|
401
|
+
Rendered users/index.html.erb within layouts/application (38.4ms)
|
402
|
+
|
403
|
+
CACHE User Load (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 [["id", 2], ["LIMIT", 1]]
|
404
|
+
|
405
|
+
↳ app/views/layouts/application.html.erb:48
|
406
|
+
|
407
|
+
(0.7ms) SELECT COUNT(*) FROM `notifications` WHERE `notifications`.`visited_id` = 2 AND `notifications`.`checked` = FALSE AND `notifications`.`action` = 'message'
|
408
|
+
|
409
|
+
↳ app/helpers/notifications_helper.rb:54
|
410
|
+
|
411
|
+
(0.8ms) SELECT COUNT(*) FROM `notifications` WHERE `notifications`.`visited_id` = 2 AND `notifications`.`action` != 'message' AND `notifications`.`checked` = FALSE
|
412
|
+
|
413
|
+
↳ app/helpers/notifications_helper.rb:48
|
414
|
+
|
415
|
+
Completed 200 OK in 342ms (Views: 304.0ms | ActiveRecord: 5.3ms)
|
416
|
+
|
417
|
+
```
|
1
各ユーザーの言語情報を rails c の内容を元に編集致しました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -130,15 +130,41 @@
|
|
130
130
|
|
131
131
|
```
|
132
132
|
|
133
|
-
各ユーザーの言語情報は以下の様に保存されて
|
133
|
+
各ユーザーの言語情報は以下の様に保存されておりましたので、なぜこれでユーザーCがヒットにならないのかが分かりません…。
|
134
134
|
|
135
135
|
|
136
136
|
|
137
|
-
|
137
|
+
```
|
138
138
|
|
139
|
-
|
139
|
+
[27] pry(main)> User.find(1).language_ids
|
140
140
|
|
141
|
+
User Load (4.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
|
142
|
+
|
143
|
+
(4.9ms) SELECT `languages`.`id` FROM `languages` INNER JOIN `user_languages` ON `languages`.`id` = `user_languages`.`language_id` WHERE `user_languages`.`user_id` = 1
|
144
|
+
|
145
|
+
=> [1]
|
146
|
+
|
147
|
+
|
148
|
+
|
141
|
-
|
149
|
+
[28] pry(main)> User.find(2).language_ids
|
150
|
+
|
151
|
+
User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
|
152
|
+
|
153
|
+
(0.8ms) SELECT `languages`.`id` FROM `languages` INNER JOIN `user_languages` ON `languages`.`id` = `user_languages`.`language_id` WHERE `user_languages`.`user_id` = 2
|
154
|
+
|
155
|
+
=> [1, 2]
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
[29] pry(main)> User.find(3).language_ids
|
160
|
+
|
161
|
+
User Load (2.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
|
162
|
+
|
163
|
+
(2.3ms) SELECT `languages`.`id` FROM `languages` INNER JOIN `user_languages` ON `languages`.`id` = `user_languages`.`language_id` WHERE `user_languages`.`user_id` = 3
|
164
|
+
|
165
|
+
=> [1, 2, 3]
|
166
|
+
|
167
|
+
```
|
142
168
|
|
143
169
|
|
144
170
|
|