Dekonstruktion Schienen .Verknüpfungen & .wo Methoden
Ich habe zwei Modelle - Banner
und BannerType
.
Ihre schema sieht wie folgt aus:
Banner
# Table name: banners
#
# id :integer not null, primary key
# name :string(255)
# image :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# url :string(255)
# banner_type_id :integer
BannerType
# Table name: banner_types
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
Banner belongs_to :banner_type
und BannerType has_many :banners
Habe ich zwei Datensätze in BannerType, sind diese:
BannerType.all
BannerType Load (0.3ms) SELECT "banner_types".* FROM "banner_types"
=> [#<BannerType id: 1, name: "Featured", created_at: "2012-12-17 04:35:24", updated_at: "2012-12-17 04:35:24">, #<BannerType id: 2, name: "Side", created_at: "2012-12-17 04:35:40", updated_at: "2012-12-17 04:35:40">]
Wenn dann will ich eine Abfrage, um herauszufinden, alle Banner der Typ Featured
kann ich tun so etwas wie dieses:
Banner.joins(:banner_type).where("banner_types.name = ?", 'Featured')
Ich weiß, ich könnte auch Abfragen, indem Sie die banner_type_id => 1
aber das ist germane zu diesem speziellen Frage.
Wenn wir brechen diese Aussage, es gibt ein paar Dinge, die sind ein bisschen verwirrend für mich.
Banner.join(:banner_type)
- erzeugen würdeNoMethodError: undefined method 'join' for #<Class:0x007fb6882909f0>
Warum gibt es keine Schienen Methode namensjoin
wenn das der SQL-Methode name?- Warum Tue ich
Banner.joins(:banner_type)
d.h. der singularbanner_type
wenn der name der Tabelle istbanner_types
. Bin ich nicht an die Banner - & BannerType Tabellen (die Rails Konventionen bezeichnen als plural). Wenn ich versucheBanner.joins(:banner_types)
dies ist die Fehlermeldung, die ich bekomme:Banner.joins(:banner_types)
ActiveRecord::ConfigurationError: Association named 'banner_types' was not found; perhaps you misspelled it? - Warum die
where
- Klausel müssenbanner_types
und nichtbanner_type
(d.h. der pluralisiert version - also der name der Tabelle und nicht das symbol in derjoins
Methode? Es scheint, es wäre intuitiver, wenn Sie die Namen der Tabellen sind in beiden Orten oder verwenden Sie den symbol-Namen, die in beiden Orten. Wenn zumindest aus Gründen der Konsistenz verwenden. - Warum kann ich das nicht dynamische Suche über Verbände - D. H. es wäre schön, wenn ich könnte
Banner.find_by_banner_type_name("Featured")
?
Würde lieben, Ihre Gedanken zu hören.
Dank.
InformationsquelleAutor marcamillion | 2012-12-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
#1
Ist es klarer, wenn Sie Lesen als nur Englisch zu sagen "Banner schließt banner-Typ" vs. "Banner join-banner-Typ". Ich bin mir nicht sicher, es gibt noch mehr Gründe als die.
#2
In
.joins(:banner_type)
,:banner_type
ist die Beziehung Sie treten auf, nicht die Tabelle. Sie habenso, dass ist das, was Rails anschließt. Das ist nur, wie Schienen arbeiten wenn Sie an einem Symbol zu
.joins
, und das ist, warum der Fehler bezieht sich auf den Verein an, wenn ein Symbol nicht passend zu jedem vorhandenen assocation für Ihr Modell.Dies ist auch der Grund, warum Sie in der Lage sind zu tun
JOIN
's mehrere Ebenen tief durch die Verwendung von Symbolen für die verschachtelte Verbände, wie beschrieben in der Rails-GuideEbenfalls beschrieben in der Rails-Guide, können Sie übergeben Sie Zeichenfolgen zu
.joins
als gut.Hinweis: in diesem letzten Beispiel, wenn ein String übergeben wird
joins
, die Tabelle nameaddresses
verwendet wird, nicht ein Verein name; dies hilft, die Antwort #3.#3
Nach einem bit-string-interpolation, Strings, der an die
where
Methode (ähnlichjoins
) sind mehr oder weniger direkt übergeben in der letzten SQL-Abfrage (es wird ein bisschen manipulation von ARel entlang des Weges).name
ist eine mehrdeutige Spalte (sowohl Ihrebanners
undbanner_types
Tabellen haben einename
Spalte), also verweisen auf die Tabelle, indem Sie den vollständigen Pfad[TABLE NAME].[COLUMN NAME]
erforderlich ist. Wenn, zum Beispiel, Sie hatten einigecolor
Spalte inbanner_types
(nicht-gibt es auchbanners
), es gibt keine Notwendigkeit, es zu benutzen, wie"banner_types.color = ?"
in Ihremwhere
Methode;"color = ?"
gut funktionieren wird.Hinweis, wie in #2, können Sie pass-Symbole, um die
where
Methode fürJOIN
'd Tabellen.#4
Können Sie nicht finden würde, weil es nicht unterstützt wird in ARel, so einfach ist das wirklich (IMO, den Namen einer Methode wie
find_by_banner_type_name
ziemlich verwirrend).BannerType.find_by_name('Featured').banners
. Das wäre irgendwie befriedigen meine Letzte Frage, obwohl er ein wenig nach hinten. Ich bekomme dein Punkt, obwohl...das kann ein bisschen verwirrend....Re: #2, ich habe nicht
has_one :banner_type
ausdrücklich. Werden Sie sagen, dass, weilBanner belongs_to :banner_type
? Also, in Effekt ist einhas_one
Beziehung?Funktioniert die Abfrage (join) auch arbeiten, ohne die
has_one
association definiert? Ich habe nie versucht. Ich bin auch neugierig, wenn es gibt einen Grund, warum man nicht haben, die explizit definiert.Es funktioniert perfekt gerade jetzt, und ich habe nicht
has_one
definiert. Ich habe nurhas_many :banners
auf dieBannerType
Modell, undbelongs_to :banner_type
auf dieBanner
Modell. Funktioniert wie ein Charme.spät zur party, aber wie in #1 :
join
ist eine Methode, die aufArray
; alsActiveRecord::Relation
Delegierten jede Methode, die nicht wissen, um eine zugrunde liegende faul geladenArray
von Datensätzen, wenn Sie anrufenjoin
Sie schlagen die array-Methode. Ich denke, der Grund fürjoins
mit einem extras
1) Vermeidung von Verwechslungen zwischen den Methoden 2) vermeiden Sie die Maskierung derjoin
Methode (frag mich nicht warum, ich sehe nicht, in welchem Fall es wäre hilfreich) 3) stellen SieRelation
's-Schnittstelle fühlen Sie sich wie ein array auf SteroidenInformationsquelleAutor deefour