Lorsque vous obtenez des données avec ActiveRecord, vous obtenez essentiellement tous les éléments du tableau correspondant. Comme vous pouvez le voir dans le SQL à émettre, tous les éléments sont acquis avec *. Puisque tous les articles ont été acquis, n'importe quel article peut être référencé dans le traitement suivant.
pry(main)> user = User.first
User Load (0.7ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
=> #<User id: 1, name: "ham", created_at: "2020-03-10 01:03:37", updated_at: "2020-06-16 02:18:39">
pry(main)> user.id
=> 1
pry(main)> user.name
=> "ham"
Cependant, toutes les colonnes ne sont pas utilisées, alors pourquoi ne pas obtenir uniquement les colonnes nécessaires? Je pense qu'il y a aussi l'idée. Dans ce cas, vous pouvez affiner les colonnes à acquérir en utilisant la méthode appelée select. Pour plus d'informations sur select, reportez-vous au [Rails Guide](https://railsguides.jp/active_record_querying.html#%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%95%E3%82% A3% E3% 83% BC% E3% 83% AB% E3% 83% 89% E3% 81% A0% E3% 81% 91% E3% 82% 92% E5% 8F% 96% E3% 82% 8A% Voir E5% 87% BA% E3% 81% 99).
Vous ne pouvez obtenir que les colonnes requises en spécifiant select. Bien entendu, les colonnes qui n'ont pas été acquises ne peuvent pas être référencées dans le traitement ultérieur.
pry(main)> user = User.select(:id, :created_at).first
User Load (0.7ms) SELECT `users`.`id`, `users`.`created_at` FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
=> #<User id: 1, created_at: "2020-03-10 01:03:37">
pry(main)> user.id
=> 1
pry(main)> user.name
ActiveModel::MissingAttributeError: missing attribute: name
from /usr/local/bundle/gems/activemodel-6.0.3.2/lib/active_model/attribute.rb:221:in `value'
C'est juste mon opinion personnelle, mais si vous développez avec plusieurs personnes comme le développement d'équipe, je pense qu'il vaut mieux ne pas utiliser select qui ne fait que réduire les colonnes.
Voir le code ci-dessous.
def hoge(user_id)
#identifiant avec select,Obtenez uniquement le nom
user = User.select(:id, :name).find(user_id)
...(Traitement divers)
generate_response(user)
end
private
def generate_response(user)
{ id: user.id, name: user.name }
end
Et si vous décidiez plus tard d'ajouter un e-mail à la réponse de la méthode hoge? Supposons que le modèle User a une colonne email.
Vous avez probablement juste besoin de le trouver et d'ajouter un e-mail à generate_response! Je pense que je vais résoudre le problème comme suit.
def generate_response(user)
- { id: current_user.id, name: current_user.name }
+ { id: current_user.id, name: current_user.name, email: current_user.email }
end
La correction est terminée! Cela a été fait en une seule ligne! !! Exécution du test! !! !!
pry(main)> { id: user.id, name: user.name, email: user.email }
ActiveModel::MissingAttributeError: missing attribute: email
from /usr/local/bundle/gems/activemodel-6.0.3.2/lib/active_model/attribute.rb:221:in `value'
cette? ?? Ça ne marche pas ... L'utilisateur destinataire est-il étrange? Suivez-moi ...
C'est vrai. Étant donné que la colonne d'acquisition est réduite par sélection, il est nécessaire d'y ajouter un e-mail. Si vous modifiez ce qui suit, cela fonctionnera.
def hoge(user_id)
#identifiant avec select,Obtenez uniquement le nom
- user = User.select(:id, :name).find(user_id)
+ user = User.select(:id, :name, :email).find(user_id)
Le test s'est bien passé!
pry(main)> { id: user.id, name: user.name, email: user.email }
=> {:id=>1, :name=>"hoge", :email=>"[email protected]"}
Si vous utilisez Rails ActiveRecord, vous obtiendrez toutes les colonnes de base, donc je pense que beaucoup de gens en sont accro une fois comme mentionné ci-dessus.
Ce n'est peut-être pas autant d'efforts à chaque fois, mais la même chose se produit à chaque fois si le système est continuellement développé. C'est un bon prix. Dans le pire des cas, cela peut même passer inaperçu et créer des bugs.
Est-il nécessaire de mettre en œuvre cette sélection pour augmenter le coût de développement et le risque de bugs? Je préfère un code que les autres ont du mal à mal comprendre, même s'il est un peu moins optimal. C'est pourquoi je pense qu'il vaut mieux ne pas utiliser select, que j'utilise juste pour affiner les colonnes.
C'est devenu un article qui nie complètement l'existence de select, mais il a bien sûr quelques utilisations. C'est lorsque la fonction d'agrégation est utilisée comme indiqué ci-dessous.
users_group_by_name = User.select('name, count(*) AS cnt').group(:name)
users_group_by_name.each do |u|
p u.name
# u.Vous pouvez obtenir le décompte avec cnt
p u.cnt
end
Cependant, même dans ce cas, il est fort probable que vous vous mépreniez si le nom de la variable est changé en ʻusers`, il est donc préférable d'utiliser un nom de variable compréhensible.
Aussi, parfois je permet d'accéder directement à la table à laquelle j'ai rejoint en utilisant select, mais c'est aussi très difficile à comprendre, donc je pense qu'il vaut mieux l'arrêter.
review = Review.select('reviews.id, users.name').joins(:user).find_by(id: 1)
#Maintenant utilisateur.peut accéder au nom
review.name
Accès via l'association normalement ou implémenter un délégué.
app/models/review.rb
review = Review.find_by(id: 1)
#Accès via association
review.user.name
#Ou définir un délégué dans le modèle de révision(delegate :name, to: :user, prefix: true)
review.user_name
Cet article était axé sur la sélection, mais je pense qu'il est important d'écrire un code facile à comprendre pour les autres (difficile à mal comprendre) dans le développement d'équipe où plusieurs personnes touchent le même code. L'écriture d'un code facile à lire (difficile à mal comprendre) accélérera le développement et réduira les bogues.