[RUBY] Sélectionnez au hasard 100 enregistrements de DB

Lorsque j'ai sauvegardé certaines données, je voulais associer 100 utilisateurs à ces données au hasard.

En guise de préparation, créez une nouvelle table pour lier la «table qui gère les données enregistrées» et la «table qui gère l'utilisateur». Les détails seront expliqués plus tard.

Tout d'abord, dans la méthode qui enregistre les données d'origine, appelez la méthode sélectionnée par l'utilisateur.

if @item.save
      destination_select()

Ensuite, nous écrirons une méthode pour sélectionner les utilisateurs.

En tant que politique

① Préparez un tableau vide (2) Obtenez l'ID utilisateur au hasard en utilisant la fonction rand ③ Si l'ID acquis n'est pas inclus dans le tableau, enregistrez-le en plus du tableau. ④ S'il est inclus, refaites la fonction rand </ b>

Ce sera.

Regardons chacun d'eux.

① Préparez un tableau vide </ b>

def destination_select
    user_ids = []                             
  end

② Obtenez l'ID utilisateur de manière aléatoire en utilisant la fonction rand </ b> La plage est définie avec le nombre d'enregistrements dans le modèle User comme argument de la fonction rand. Aussi, cette fois, je veux avoir 10 personnes, donc je répète cela 10 fois avec la méthode des temps.

 def destination_select
    user_ids = []
    100.times do |i|
      user_id = (rand(User.count))
    end
  end

③ Si l'id acquis n'est pas inclus dans le tableau, enregistrez-le en plus du tableau L'id obtenu est poussé vers le tableau user_ids. Aussi, dans le "tableau des liens" préparé à l'avance ici, Sauvegardez l'enregistrement avec l'id de @item défini par l'appelant et l'ID utilisateur obtenu par la fonction rand comme arguments.
 def destination_select
    user_ids = []
    100.times do |i|
      user_id = (rand(User.count))
      #Décrivez l'expression conditionnelle de ④ ici
      user_ids.push(user_id)
      Destination.create(item_id: @item.id, user_id: user_id)
    end
  end

④ S'il est inclus, refaites la fonction rand Si cela est laissé tel quel, user_id peut être dupliqué à la suite de la fonction rand. Par conséquent, il est jugé si l'identifiant acquis par la méthode include? Ne chevauche pas l'identifiant acquis jusqu'à présent et noté dans le tableau, et la fonction rand est répétée jusqu'à ce qu'il n'y ait pas de duplication.
 def destination_select
    user_ids = []
    100.times do |i|
      user_id = (rand(User.count))
      while user_ids.include?(user_id) do
        user_id = (rand(User.count)) 
      end
      user_ids.push(user_id)
      Destination.create(item_id: @item.id, user_id: user_id)
    end
  end

C'est tout ce qu'on peut en dire.

6
8
42
85
93
75
5
40
79
23
17
13
88
74
54
62
64
26
35
70
14
49
63
28
81
98
69
94
0
91
87
55
84
83
9
36
80
78
30
12
3
92
20
24
2
67
34
43
16
95
86
38
22
77
97
11
25
21
90
1
51
65
53
68
37
58
56
47
18
15
41
29
89
59
52
44
46
48
82
57
10
50
45
60
66
7
32
76
4
19
27
61
96
39
71
72
33
31
99
73

J'ai pu récupérer et enregistrer au hasard les identifiants de 100 personnes sans duplication.

Postscript

Comme vous l'avez souligné dans les commentaires, je voudrais ajouter deux points.
(1) Dans le cas ci-dessus, 0 est inclus en raison de la nature de la fonction rand. Étant donné que l'ID utilisateur de 0 n'existe pas, il est nécessaire d'ajouter +1. </ b>

(2) En tant que méthode d'acquisition aléatoire, ce qui suit est une vitesse de traitement plus rapide et une description plus simple. </ b>

User.order("random()").limit(100).pluck(:id) # sqlite/pg
User.order("rand()").limit(100).pluck(:id) # mysql
user_ids = User.order("random()").limit(100).pluck(:id)
user_ids.each{|user_id| Destination.create(item_id: @item.id, user_id: user_id) }

Merci d'avoir souligné.