Ruby on Rails - 2つのテーブルを結合するには?

私は1対多の関係で2つのテーブル(件名とページ)を持っています。私は主題からの基準をSQLの構文解析に加えてページに追加したいが、進捗状況は非常に遅く、しばしば問題に陥っている。私は真新しいレールで、助けてください。

class Subject < ActiveRecord::Base
  has_many :pages
end

class Page < ActiveRecord::Base
  belongs_to :subject 
end

被験者のサンプルデータは、以下の3列に記載されています。

id  name    level
1   'Math'  1
6   'Math'  2
...

サンプルデータ(ページ数)

id  name                    subject_id
--  --------------------    ----------
2   Addition                1
4   Subtraction             1
5   Simple Multiplication   6
6   Simple Division         6
7   Hard Multiplication     6
8   Hard Division           6
9   Elementary Divsion      1

私がsubject.idを知らないとすれば、私は主語の名前とレベル、およびページ名しか知りません。ここでは、私は生成するSQL(または同様の結果を得るだろう同様のもの)です:

select subjects.id, subjects.name, pages.id, pages.name from subjects, pages
 where subjects.id = pages.subject_id
   and subjects.name = 'Math'
   and subjects.level = '2'
   and pages.name like '%Division'  ;

私は結果に2行を期待しています:

subjects.id     subjects.name   pages.id    pages.name 
-----------     -------------   --------    -----------
6               Math            6           Simple Division
6               Math            8           Hard Division

これは非常にシンプルなSQLですが、私はレールで欲しいと思ってもらえませんでした。

Here is my rails console:  

>> subject = Subject.where(:name => 'Math', :level => 2)
  Subject Load (0.4ms)  SELECT `subjects`.* FROM `subjects` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2
[#]
>> 
>> subject.joins(:pages).where(['pages.name LIKE ?', '%Division'])
  Subject Load (4.2ms)  SELECT `subjects`.* FROM `subjects` INNER JOIN `pages` ON `pages`.`subject_id` = `subjects`.`id` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2 AND (pages.name LIKE '%Division')
[#, #]
>> 
>> subject.to_sql
"SELECT `subjects`.* FROM `subjects`  WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2"
>> subject.size
1
>> subject.class
ActiveRecord::Relation

1st statement: subject = Subject.where(:name => 'Math', :level => 2) 2nd statement: subject.joins(:pages).where(['pages.name LIKE ?', '%Division'])

質問:

  1. 連鎖されたSQLの結果は実際には2つの行を返しますが、subject.sizeには1だけしか表示されません。
  2. ページからも列を返すようにするにはどうすればよいですか?
  3. なぜsubject.to_sqlにsql from文1のみが表示されるのですか?なぜ、statement 2の連鎖SQLは含まれませんでしたか?
  4. 基本的には、上記のSQL構文解析のためにステートメントを異なる方法で記述する必要がありますか(同じ結果が得られますか?)

どうもありがとう。

1

1 答え

1)ActiveRecordは、返された任意の行ではなくオブジェクトにクエリ結果をマップするので、結果の行を見ている Subject クラスのクエリの作成に基づいている1つの一意の Subject オブジェクトのみを参照しているので、単一の Subject インスタンスを返します。

2)列データはありますが、あなたはActiveRecordがあなたに与えたいもの、つまりオブジェクトです。 Pagesを返すようにするには、 Page クラスに基づいてクエリの作成を行う必要があります。

3) join(:pages)... subject 変数に追加した結果を保存しませんでした。あなたがした場合:

subject = subject.joins(:pages).where(['pages.name LIKE ?', '%Division'])

You would get the full query when running subject.to_sql

4)ページオブジェクトを取得するには、このようなことをすることができますが、 Page クラスを基にしています。

pages = Page.joins(:subject).where(['subjects.name = ? AND subjects.level = ? AND pages.name LIKE ?', 'Math', 2, '%Division'])

次に、返された最初の Page オブジェクトの件名にアクセスします。

pages[0].subject.name

これは最初に結合があるため、別のSQLクエリーにはなりません。お役に立てれば!

4
追加された
ブリリアント!!!どうもありがとうございます。あなたは私のすべての質問に答える、今はうまくいく。 :-)
追加された 著者 jmsia,