2011-12-19 9 views
1

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

:の下、ページに記載されている列を

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

サンプルデータ:被験者で

class Subject < ActiveRecord::Base 
    has_many :pages 
end 

class Page < ActiveRecord::Base 
    belongs_to :subject 
end 

サンプルデータは、以下の3つの列がリストされています。 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 id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", 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 id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", level: 2>, #<Subject id: 6, name: "Math", position: 1, visible: true, created_at: "2011-12-17 04:25:54", updated_at: "2011-12-17 04:25:54", level: 2>] 
>> 
>> subject.to_sql 
"SELECT `subjects`.* FROM `subjects` WHERE `subjects`.`name` = 'Math' AND `subjects`.`level` = 2" 
>> subject.size 
1 
>> subject.class 
ActiveRecord::Relation 

第一の文:件名= Subject.where(:名=> '数学'、:レベル=> 2) 第二の文:subject.joins(:ページ).where([ 'ページ.nameのLIKE「、 '%部門'])

質問:?チェーンSQLは実際に2つの行を返すの

  1. 結果が、subject.sizeはわずか1言いますか?
  2. ページの列を返すように指示するにはどうすればよいですか?
  3. なぜsubject.to_sqlにはsql from文1のみが表示されるのですが、なぜそれが文2の連鎖SQLを含まないのですか?
  4. 本質的に、上記のようにSQLを解析する(または同じ結果を得る)ためには、文を別に書く必要がありますか?

多くのありがとう。

答えて

4

1)ActiveRecordのは、あなたがそれはあなたの結果の行を見ているSubjectクラスのオフクエリの作成をベースとし、それだけで参照していることを数字ためので、オブジェクトにない任意の返された行をクエリの結果をマップするために起こっています1つのユニークなSubjectオブジェクトであるため、単一のSubjectインスタンスのみを返します。

2)カラムのデータはありますが、あなたはActiveRecordがあなたに与えたいもの、つまりオブジェクトです。 Pagesを返す場合は、Pageクラスのクエリの作成をベースにする必要があります。

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

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

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クエリが生成されることはありません。お役に立てれば!

+0

華麗な!!!どうもありがとうございます。あなたは私のすべての質問に答える、今はうまくいく。 :-) – jmsia

関連する問題