Ik ben nieuw op het gebied van rails. Wat ik zie dat er veel manieren zijn om een record te vinden:
find_by_<columnname>(<columnvalue>)
find(:first, :conditions => { <columnname> => <columnvalue> }
where(<columnname> => <columnvalue>).first
En het lijkt erop dat ze allemaal precies dezelfde SQL genereren. Ik geloof ook dat hetzelfde geldt voor het vinden van meerdere records:
find_all_by_<columnname>(<columnvalue>)
find(:all, :conditions => { <columnname> => <columnvalue> }
where(<columnname> => <columnvalue>)
Is er een vuistregel of aanbeveling welke te gebruiken?
Antwoord 1, autoriteit 100%
Bewerken:
Dit antwoord is erg oud en er zijn andere, betere antwoorden naar voren gekomen sinds dit bericht is gemaakt. Ik raad aan om de onderstaande door @Hossam Khamis te bekijken voor meer details.
Gebruik degene die het beste bij je past.
De find
methode wordt meestal gebruikt om een rij op ID op te halen:
Model.find(1)
Het is vermeldenswaard dat find
een uitzondering genereert als het item niet wordt gevonden door het kenmerk dat u opgeeft. Gebruik where
(zoals hieronder beschreven, wat een lege array retourneert als het kenmerk niet wordt gevonden) om te voorkomen dat er een uitzondering wordt gegenereerd.
Andere toepassingen van find
worden meestal vervangen door dingen als deze:
Model.all
Model.first
find_by
wordt gebruikt als hulp bij het zoeken naar informatie in een kolom, en het verwijst naar deze met naamgevingsconventies. Als u bijvoorbeeld een kolom met de naam name
in uw database heeft, gebruikt u de volgende syntaxis:
Model.find_by(name: "Bob")
.where
is meer een vangst waarmee je een wat complexere logica kunt gebruiken voor wanneer de conventionele helpers het niet zullen doen, en het retourneert een reeks items die voldoen aan je voorwaarden (of anders een lege array).
Antwoord 2, autoriteit 97%
waarActiveRecord::Relation retourneert
Kijk nu eens naar de find_by-implementatie:
def find_by
where(*args).take
end
Zoals je kunt zien is find_byhetzelfde als where, maar het retourneert slechts één record. Deze methode moet worden gebruikt om 1 record te krijgen en waarmoet worden gebruikt om alle records met bepaalde voorwaarden te krijgen.
Antwoord 3, autoriteit 41%
Model.find
1- Parameter: ID van het te vinden object.
2- Indien gevonden: het retourneert het object (slechts één object).
3- Indien niet gevonden: genereert een ActiveRecord::RecordNotFound
uitzondering.
Model.find_by
1- Parameter: sleutel/waarde
Voorbeeld:
User.find_by name: 'John', email: '[email protected]'
2- Indien gevonden: het geeft het object terug.
3- Indien niet gevonden: retourneert nil
.
Opmerking:Als je wilt dat het ActiveRecord::RecordNotFound
verhoogt, gebruik dan find_by!
Model.where
1- Parameter: hetzelfde als find_by
2- Indien gevonden: het retourneert ActiveRecord::Relation
met een of meer records die overeenkomen met de parameters.
3- Indien niet gevonden: het retourneert een Leeg ActiveRecord::Relation
.
Antwoord 4, autoriteit 30%
Er is een verschil tussen find
en find_by
doordat find
een fout retourneert als deze niet wordt gevonden, terwijl find_by
geeft null terug.
Soms is het gemakkelijker te lezen als je een methode hebt zoals find_by email: "haha"
, in tegenstelling tot .where(email: some_params).first
.
Antwoord 5, autoriteit 16%
Sinds Rails 4 kun je het volgende doen:
User.find_by(name: 'Bob')
wat het equivalent is find_by_name
in Rails 3.
Gebruik #where
wanneer #find
en #find_by
niet genoeg zijn.
Antwoord 6, autoriteit 7%
Het geaccepteerde antwoord dekt over het algemeen alles, maar ik wil graag iets toevoegen,
voor het geval u van plan bent om met het model te werken op een manier zoals bijwerken, en u een enkele record ophaalt (waarvan u de id
niet kent), dan is find_by
de te gaan, omdat het de record ophaalt en niet in een array plaatst
irb(main):037:0> @kit = Kit.find_by(number: "3456")
Kit Load (0.9ms) SELECT "kits".* FROM "kits" WHERE "kits"."number" =
'3456' LIMIT 1
=> #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56",
updated_at: "2015-05-12 06:10:56", job_id: nil>
irb(main):038:0> @kit.update(job_id: 2)
(0.2ms) BEGIN Kit Exists (0.4ms) SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" =
1 [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]]
(0.6ms) COMMIT => true
maar als je where
gebruikt, kun je het niet rechtstreeks bijwerken
irb(main):039:0> @kit = Kit.where(number: "3456")
Kit Load (1.2ms) SELECT "kits".* FROM "kits" WHERE "kits"."number" =
'3456' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456",
created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58",
job_id: 2>]>
irb(main):040:0> @kit.update(job_id: 3)
ArgumentError: wrong number of arguments (1 for 2)
in zo’n geval zou je het als volgt moeten specificeren
irb(main):043:0> @kit[0].update(job_id: 3)
(0.2ms) BEGIN Kit Exists (0.6ms) SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1
[["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]]
(0.5ms) COMMIT => true
Antwoord 7, autoriteit 6%
Naast het geaccepteerde antwoord is het volgende ook geldig
Model.find()
kan een reeks id’s accepteren en zal alle records retourneren die overeenkomen.
Model.find_by_id(123)
accepteert ook array, maar verwerkt alleen de eerste id-waarde die aanwezig is in array
Model.find([1,2,3])
Model.find_by_id([1,2,3])
Antwoord 8, autoriteit 5%
De tot nu toe gegeven antwoorden zijn allemaal OK.
Een interessant verschil is echter dat Model.find
zoekt op id; indien gevonden, retourneert het een Model
object (slechts een enkele record), maar genereert anders een ActiveRecord::RecordNotFound
.
Model.find_by
lijkt erg op Model.find
en laat je in elke kolom of groep kolommen in je database zoeken, maar het geeft nil
als er geen record overeenkomt met de zoekopdracht.
Model.where
aan de andere kant retourneert een Model::ActiveRecord_Relation
-object dat lijkt op een array met alle records die overeenkomen met de zoekopdracht. Als er geen record is gevonden, wordt een leeg Model::ActiveRecord_Relation
-object geretourneerd.
Ik hoop dat deze u op elk moment kunnen helpen om te beslissen welke u wilt gebruiken.
Antwoord 9, autoriteit 4%
Stel dat ik een model User
. heb
User.find(id)
Retourneert een rij waarbij primaire sleutel = id. Het retourtype is User
object.
User.find_by(email:"[email protected]")
Retourneert in dit geval de eerste rij met overeenkomend kenmerk of e-mailadres. Het retourtype is opnieuw User
-object.
Opmerking:- User.find_by(email: "[email protected]")
is vergelijkbaar met User.find_by_email("[email protected]")
User.where(project_id:1)
Retourneert alle gebruikers in de gebruikerstabel waar het kenmerk overeenkomt.
Hier is het retourtype ActiveRecord::Relation
object. De klasse ActiveRecord::Relation
bevat Ruby’s Enumerable
-module, zodat u het object als een array kunt gebruiken en erop kunt doorkruisen.
Antwoord 10, autoriteit 4%
Beide #2’s in je lijsten worden beëindigd. Je kunt echter nog steeds find(params[:id])
gebruiken.
Over het algemeen werkt where()
in de meeste situaties.
Hier is een geweldige post: https://web.archive.org/web/20150206131559/http://m.onkey.org/active-record-query-interface
Antwoord 11
Het beste van werken met open source-technologie is dat je de lengte en de breedte ervan kunt inspecteren.
Bekijk deze link
find_by ~> Vindt de eerste record die aan de opgegeven voorwaarden voldoet. Er is geen impliciete bestelling, dus als de volgorde belangrijk is, moet u deze zelf specificeren. Als er geen record wordt gevonden, wordt nul geretourneerd.
vind ~> Vindt het eerste record dat aan de opgegeven voorwaarden voldoet, maar als er geen record wordt gevonden, wordt er een uitzondering gemaakt, maar dat is opzettelijk gedaan.
Kijk naar de bovenstaande link, deze heeft alle uitleg en gebruiksscenario’s voor de volgende twee functies.
Antwoord 12
Ik zal persoonlijk aanbevelen om
. te gebruiken
where(< columnname> => < columnvalue>)