Wenn Sie Daten mit ActiveRecord abrufen, erhalten Sie grundsätzlich alle Elemente in der entsprechenden Tabelle. Wie Sie aus dem auszugebenden SQL sehen können, werden alle Elemente mit * erfasst. Da alle Artikel erworben wurden, kann in der nachfolgenden Verarbeitung auf jeden Artikel verwiesen werden.
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"
Es werden jedoch nicht alle Spalten verwendet. Warum also nicht nur die erforderlichen Spalten abrufen? Ich denke da ist auch die Idee. In einem solchen Fall können Sie die zu erfassenden Spalten mithilfe der Methode select eingrenzen. Weitere Informationen zur Auswahl finden Sie in [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% Siehe E5% 87% BA% E3% 81% 99).
Sie können nur die erforderlichen Spalten abrufen, indem Sie select angeben. Natürlich können die nicht erfassten Spalten in der nachfolgenden Verarbeitung nicht referenziert werden.
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'
Es ist nur meine persönliche Meinung, aber wenn Sie mit mehreren Personen wie der Teamentwicklung entwickeln, ist es meiner Meinung nach besser, keine Auswahl zu verwenden, die nur die Spalten einschränkt.
Siehe den Code unten.
def hoge(user_id)
#ID mit Auswahl,Holen Sie sich nur Namen
user = User.select(:id, :name).find(user_id)
...(Verschiedene Verarbeitung)
generate_response(user)
end
private
def generate_response(user)
{ id: user.id, name: user.name }
end
Was ist, wenn Sie später beschlossen haben, der Antwort der Hoge-Methode eine E-Mail hinzuzufügen? Nehmen wir an, dass das Benutzermodell eine E-Mail-Spalte hat.
Sie müssen es wahrscheinlich nur finden und E-Mail zu generate_response hinzufügen! Ich denke, dass ich es wie folgt beheben werde.
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
Okay, die Korrektur ist vorbei! Es wurde in einer Zeile gemacht! !! Test Ausführung! !! !!
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'
Das? ?? Es funktioniert nicht ... Ist der empfangende Benutzer seltsam? Folge mir ...
Korrekt. Da die Erfassungsspalte durch Auswahl eingegrenzt wird, muss eine E-Mail hinzugefügt werden. Wenn Sie Folgendes ändern, funktioniert es.
def hoge(user_id)
#ID mit Auswahl,Holen Sie sich nur Namen
- user = User.select(:id, :name).find(user_id)
+ user = User.select(:id, :name, :email).find(user_id)
Der Test verlief gut!
pry(main)> { id: user.id, name: user.name, email: user.email }
=> {:id=>1, :name=>"hoge", :email=>"[email protected]"}
Ich denke, wenn Sie Rails ActiveRecord verwenden, erhalten Sie alle grundlegenden Spalten, daher denke ich, dass viele Menschen wie oben erwähnt einmal davon abhängig sind.
Es ist vielleicht nicht jedes Mal so viel Aufwand, aber jedes Mal passiert das Gleiche, wenn das System kontinuierlich weiterentwickelt wird. Das ist ein guter Preis. Im schlimmsten Fall kann es sogar unbemerkt bleiben und Fehler verursachen.
Ist es notwendig, diese Auswahl zu implementieren, um die Entwicklungskosten und das Fehlerrisiko zu erhöhen? Ich bevorzuge Code, der für andere schwer zu missverstehen ist, auch wenn er etwas weniger optimal ist. Deshalb denke ich, dass es besser ist, select nicht zu verwenden, was ich nur benutze, um die Spalten einzugrenzen.
Es ist zu einem Artikel geworden, der die Existenz von Select vollständig leugnet, aber natürlich einige Verwendungszwecke hat. In diesem Fall wird die Aggregatfunktion wie unten gezeigt verwendet.
users_group_by_name = User.select('name, count(*) AS cnt').group(:name)
users_group_by_name.each do |u|
p u.name
# u.Sie können die Zählung mit cnt erhalten
p u.cnt
end
Selbst in diesem Fall besteht jedoch eine hohe Wahrscheinlichkeit, dass es missverstanden wird, wenn der Variablenname auf "Benutzer" usw. gesetzt wird. Daher ist es besser, einen verständlichen Variablennamen zu verwenden.
Manchmal mache ich es auch möglich, mit select direkt auf die Tabelle zuzugreifen, zu der ich beigetreten bin, aber das ist auch sehr schwer zu verstehen, daher denke ich, dass es besser ist, sie zu stoppen.
review = Review.select('reviews.id, users.name').joins(:user).find_by(id: 1)
#Jetzt Benutzer.kann auf den Namen zugreifen
review.name
Zugriff über Assoziation normalerweise oder Delegat implementieren.
app/models/review.rb
review = Review.find_by(id: 1)
#Zugang über Verein
review.user.name
#Oder definieren Sie einen Delegaten im Überprüfungsmodell(delegate :name, to: :user, prefix: true)
review.user_name
Dieser Artikel konzentrierte sich auf die Auswahl, aber ich denke, es ist wichtig, Code zu schreiben, der für andere leicht zu verstehen ist (schwer zu missverstehen), wenn mehrere Personen denselben Code berühren. Das Schreiben von Code, der leicht zu lesen ist (schwer zu missverstehen), beschleunigt die Entwicklung und reduziert Fehler.
Recommended Posts