web-dev-qa-db-ja.com

結合されたテーブルからフィールドを適切に選択する方法

これが私の簡略化したモデルです、私はモデルに参加しました、

モデルマンション

   has_many :towers

そして

モデルタワー

   belong_to :apartment

そして、私はコントローラで両方のテーブルを結合しようとしましたRails console this this:

Apartment.joins(:towers).select( 'apartments.id'、 'apartments.name'、 'towers.id'、 'towers.name')

問題はクエリを超えるだけで戻ります

apartments.idとApartments.name

このようなエイリアスも使用しようとしましたが、まだ運がありません

Apartment.joins(:towers).select( 'apartments.id'、 'apartments.name'、 'towers.id as towerid'、 'towers.name as towername')

すべてのタワーにアパートがあることを確認しました。これを行うと1つのレコードを取得できます

Apartment.joins(:towers).select( 'apartments.id'、 'apartments.name'、 'towers.id'、 'towers.name')。first.towers.id

など、しかし私はすべてのレコードとそれらのすべてのフィールドが必要です、アドバイスをお願いします。

ここに私が得た最新の結果がありますRails console:

 Apt Load (1.0ms)  SELECT apts.id, apts.apt_name, towers.id as towerid, towers.
    tower_name as towername FROM `apts` INNER JOIN `towers` ON `towers`.`apt_id` = `
    apts`.`id`
    => #<ActiveRecord::Relation [#<Apt id: 5, apt_name: "basura">, #<Apt id: 5, apt_
    name: "basura">, #<Apt id: 124, apt_name: "hydra">, #<Apt id: 124, apt_name: "hy
    dra">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 142, apt_name: "apartement gajah mada">, #<Apt id: 142, apt_name: "apartement gajah mada">]>

ご覧のとおり、上記のクエリは2つのフィールドのみを返します。結果は次のようになる必要があります。

#<Apt id: 126, apt_name: "mediterania", tower_id: 12, tower_name: "tower A">, 
#<Apt id: 126, apt_name: "mediterania", tower_id: 15, tower_name: "tower F">

etcc ...

9
NomNomNom

これが可能であると私が考える唯一の方法は、asを使用することです

q = Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')

q.first.t_id
q.first.t_name

first.towers.idが機能しない理由

apartment.towersActiveRecord::Associations::CollectionProxyを返します。タワーのコレクションと考えることができます。 SQLクエリでは、towersテーブルを参照しています。しかし、apartment.towers.idを実行すると、機能しないCollectionProxyオブジェクトでidを呼び出しています。 towers.firstを使用して最初のタワーを取得できます。

について、

Apt Load (1.0ms)  SELECT apts.id, apts.apt_name, towers.id as towerid, towers.
    tower_name as towername FROM `apts` INNER JOIN `towers` ON `towers`.`apt_id` = `
    apts`.`id`
    => #<ActiveRecord::Relation [#<Apt id: 5, apt_name: "basura">, #<Apt id: 5, apt_
    name: "basura">, #<Apt id: 124, apt_name: "hydra">, #<Apt id: 124, apt_name: "hy
    dra">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 142, apt_name: "apartement gajah mada">, #<Apt id: 142, apt_name: "apartement gajah mada">]>

コンソールに表示されるのは、inspsectメソッドによって返される結果です。 inspectメソッドは、列以外の属性を表示するようには設計されていません。したがって、メモリにタワー名がある場合でも、アパートメントモデルの列である属性のみが表示されます。詳細 inspect

また、以下を試すことをお勧めします:

Apartment.joins(:towers).pluck('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')

上記のステートメントは、配列内のすべてのデータを取得します。 selectを使用しても同じ結果が得られますが、selectは配列内のすべてのデータをロードしません。

8
dnsh

あなたは使うべきです

Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id , towers.name')

これは、単一の文字列内のすべての列名です。

これを参照してください。

7
Sajan

以下のようなエイリアス名を試すことができます

Apartment.joins(:towers).select('apartments.id as apartment_id, apartments.name as apartment_name, towers.id as tower_id , towers.name as tower_name)
0
Jayaprakash