Rails AR 深い階層のテーブル参照

このQ&Aのポイント
  • Rails ActiveRecordで深い階層のテーブルを参照する方法について教えてください。
  • classDからclassAのnameを取得するために、煩雑な処理を行っています。もっとスマートな方法はありますか?
  • has_many :throughを使ってショートカットを作成する方法がわかりません。回答していただけますか?
回答を見る
  • ベストアンサー

Rails AR 深い階層のテーブル参照

Rails ActiveRecord において、 深い階層のテーブルを参照するのに有効な方法はないでしょうか? 例:下記の構造で classD から classAのnameを取得する。 classA  1→n  classB  1→n  classC  1→n  classD □classA   id   name □classB   id   name   class_a_id □classC   id   name   class_b_id □classD   id   name   class_c_id #前提条件 classC, classB, classAが必ずしも存在するとは限らない。 classDからclassAを参照する際に、#前提条件にあるように、 classB or classCが存在しない(nil)場合、 > class_d.class_c.class_b.class_a.name とするとエクセプションが発生しますが、 これを回避するために、 if class_d.class_c and class_d.class_c.class_b and class_d.class_c.class_b.class_a class_d.class_c.class_b.class_a.name end のようにしていますが、煩わしくてしかたがありません。 実際はエラーログ出力等行っているため、さらに複雑な処理になっています。 もっとスマートなコーディング方法やアドバイスがありましたら宜しくお願いします。 #補足 (1) has_many :through を使ってショートカットが作れることを知りましたが、 今回の例のように、複数階層となる場合の記述方法がわかりません。 ご存知の方回答お願いいたします。 (2) そもそも前提条件に問題があるのではないかとも思っています。 前提条件にあるような状態にならない様な仕組みにする、 もしくは、そのような状態にならないよう管理する、等すべきでしょうか? 以上宜しくお願いいたします。

  • Ruby
  • 回答数1
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

> if class_d.class_c and class_d.class_c.class_b and class_d.class_c.class_b.class_a >  class_d.class_c.class_b.class_a.name > end > のようにしていますが、煩わしくてしかたがありません。 単純に classD にそのようなメソッドを一つ定義して 他ではそれを呼び出せばいいんじゃないの?

関連するQ&A

  • 配列であるメンバのコンストラクタを呼ぶ方法

    C++のクラスについて教えていただけないでしょうか。以下のような場合、 class ClassA {   int A; public:   ClassA(int a): A(a) {} }; class ClassB {   ClassA A; public:   ClassB(): A(10) {} }; class ClassC {   ClassA A[2]; public:   ClassC() {} //配列であるメンバのコンストラクタを呼び出したい }; ClassBがClassAのコンストラクタを呼ぶには上記のような方法で良いと思うのですが、ClassCのようにメンバが配列の場合、そのメンバのコンストラクタを呼ぶにはどのようにしたら良いのでしょうか。ご教授をお願いします。

  • 「new 式」 で、変数を 式 として指定することはできますか?

    「new 式」 で、変数を 式 として指定することはできますか? 例えば次のような感じで、変数clの内容によりclassAあるいはclassBをnew するようなことがしたいです。 class base [ ... }; class classA : public base { .... }; class classB : public base { .... }; classA* ca; classB* cb; base* cl; cl = classA; ca = new cl; cl = classB; ca = new cl; これにより、多種のclassをnewする際にいちいち pa = new classA; pb = new classB; pc = new classC; pd = new classD; ............ としないで、 for (n=0; n<xxx; n++) p[n] = new cl[n]; …みたいに簡潔に書けないかなと考えてます。 よろしくお願いします。

  • 参照メンバを持つクラス

    ClassAとClassBにCMyDataオブジェクトを渡したいのですが、メモリ上に同じデータのコピーを作りたくないので、コンストラクタがCMyDataの参照を受け取る設計にしました。こうすることで、CMyDataの実体はメモリ上に1つしか存在しないことになります。 ただ、クラスが、自身が管理していない外部領域にあるデータへの参照を使って仕事をするというのに違和感を感じます。 完全コンストラクタというデザインパターンがあって、クラスのインスタンスを生成する時に必要な全てのデータを渡すのが正しい流儀だそうです。 しかしこのClassA(B)の設計では、ClassA(B)の寿命が終わるまで参照先のデータが生きているとは限りません。もっといい設計はないでしょうか?ちなみにCMyDataは実際にはかなり大きなデータで、一時的であってもコピーを複数持ちたくないのです。ClassAとClassBは、実際は他のデータも参照するため1つのクラスにはしたくないのです。 class CMyData { // 色々なデータ }; class CMain { CMyData* myData; // ファイルからデータを読み込んで生成 ClassA* objA; ClassB* objB; void ReadFile() { myData = new CMyData(); // ファイルからデータを読み込みCMyData構築 } void Init() { ReadFile(); objA = new ClassA(*myData); // 自身のメンバ変数の参照でClassAを構築 objB = new ClassB(*myData); } void DoProcess() { Init(); // 実行は一度だけ objA->hoge(); // ClassAに仕事をさせる objB->foo(); // ClassBに仕事をさせる } } class ClassA { CMyData& m_data; public: ClassA(CMyData& data) m_data=data; // CMyDataオブジェクトを参照で受け取る void hoge(); } class ClassB { CMyData& m_data; public: ClassB(CMyData& data) m_data=data; // CMyDataオブジェクトを参照で受け取る void foo(); }

  • 継承元クラスのプロパティを参照する手段

    お世話になります。 ActionScrip3に関する質問です。 現在、カスタムクラスを勉強しております。 外部クラスでClassA、ClassBを作成し、 ClassAにある処理の途中でClassBを実行し、ClassBの中からClassAのプロパティを参照しにいく 処理を行いたいと思い、ClassBのコンストラクタからClassAのプロパティをtraceしました。 プロパティppt2は「かきくけこ」が出力されましたが、ppt1は「null」になってしまいました。 恐らく、タイムラインからClassAに対して設定したプロパティの値は見にいけていないようですが、 タイムラインから設定したプロパティの値を継承したClassBから参照しにいく方法はありますでしょうか? 下記ソースと同じ方法でなくても結構ですので、タイムラインから設定した スーパークラスのプロパティ値をサブクラスから参照・変更できる方法を ご教授いただければと存じます。 お手数ではありますが、宜しくご教授ください。 宜しくお願いいたします。 /* タイムライン側の処理 -----------------------*/ var test:ClassA = new ClassA(); test.ppt1 = "あいうえお"; test.goNext(); /* ClassAの処理 -----------------------*/ package {  // インポート記述は省略  public class ClassA {   var ppt1:String;   var ppt2:String = "かきくけこ";   // コンストラクタ   public function ClassA() { }   public function goNext():void {    var classb:ClassB = new classB();   }  } } /* ClassBの処理 -----------------------*/ package {  // インポート記述は省略  public class ClassB extends ClassA {   // コンストラクタ   private function ClassB() {    trace(ppt1);    trace(ppt2); }  } }

    • ベストアンサー
    • Flash
  • インクルード元を知りたい

    PHP5.2.4を使用しています。 [a.php] <?php include("b.php"); include("c.php"); $c = new classC(); [b.php] <?php class classB { } [c.php] <?php class classC { public function __construct() { $c = new classB();//←b.phpファイルがどこでインクルードされたか知りたい } } という3つのファイルがあり、a.phpにアクセスするとします。 c.phpファイルのコンストラクタでb.phpファイルにあるclassBを生成していますが、 これはa.phpファイルにおいて先にinclude("b.php");があるので c.phpファイル内でもclassBを認識できると思います。 そこでc.phpファイル内でb.phpファイルがどこでインクルードされたか(この例ではa.phpファイル) 調べる方法なり関数というのはあるのでしょうか?

    • ベストアンサー
    • PHP
  • [Obj-c]元クラスからサブクラスのメソッド

    Objective-Cの勉強をしています。 ClassAは元クラス(スーパークラス)です、 ClassB1、B2はClassAを継承(サブクラス)しています。 ClassAとClassB1にはiMethodというメソッドが存在します。 最下部にソースと実行結果があります。 ●そこで質問なのですが、  ClassAのインスタンスにClassB1のインスタンスをセットすると、  同じ名前のメソッドがあるだけでなぜClassB1のメソッドが呼ばれるのでしょうか?  (下記ソースの[bangai iMethod]; の部分です。)  ClassB1のインスタンスを渡すとClassAのインスタンスが  ClassB1のメソッドを使用できる理由がわかりません、  継承しているとはいえ型が違うものを参照渡しできる理由も今ひとつわからないです。  またこれはどういう機能を言うのでしょうか?  (例えば ポリモーフィズム、動的バインディングなど) ★ソース ------------------------------------------------------------------------------ #import <Foundation/Foundation.h> // ClassA @interface ClassA : NSObject { } @end @implementation ClassA -(void) iMethod { NSLog(@"スーパークラスのインスタンスメソッドです。\n"); return; } @end // ClassB1 @interface ClassB1 : ClassA @end @implementation ClassB1 -(void) iMethod { NSLog(@"サブクラスのインスタンスメソッドです。\n"); return; } @end // ClassB2 @interface ClassB2 : ClassA @end @implementation ClassB2 @end int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... ClassB1 *instance_B1 = [[ClassB1 alloc]init]; ClassB2 *instance_B2 = [[ClassB2 alloc]init]; [instance_B1 iMethod]; [instance_B2 iMethod]; // 親には子のクラスが入れられる ClassA *bangai = instance_B1; [bangai iMethod]; } return 0; } ------------------------------------------------------------------------------ ★実行結果 サブクラスのインスタンスメソッドです。 スーパークラスのインスタンスメソッドです。 サブクラスのインスタンスメソッドです。

  • 違うクラスのデータを読み込むにはどうすればいいですか?

    はじめまして、Javaを勉強したばかりの初心者です。 下のようばプログラムでclassAのdata配列を class Cで参照するにはどうすればよいでしょうか? public class A extends B{ ・・・・ short data[] = new short[10]; } public class C extends D{ }

    • ベストアンサー
    • Java
  • C# クラスのインスタンスについて

    クラス(ClassA)を作成した後に別のクラス(ClassB)内でClassAインスタンスを作成したとします。 このインスタンスをさらに別のクラス(ClassC)で使用したいと思うの ですが可能なんでしょうか? 要するに1つのインスタンスを他で使いまわすような事ができないの かなって思っています。 自分で調べると「Singletonパターン」という方法があるようですが 他の方法もあれば知ってみたいと思っています。 ※環境はWinXP、VS2005 C# です。 以上ですが、よろしくお願いいたします。

  • 「オブジェクト参照渡し」と「参照渡し」の違いを

    ▽PHP: オブジェクトと参照 - Manual   http://jp.php.net/manual/ja/language.oop5.references.php $a = new A; $b = $a; // $a と $b は同じ ID を持つコピーです // ($a) = ($b) = <id> $c = new A; $d = &$c; // $c と $d は参照です // ($c,$d) = <id> とありますが、 ($a) = ($b) = <id> ($c,$d) = <id> の違いを目で見て確認できるような簡単なサンプルコードはないでしょうか? echoとかで中身を出力して、確かに違っているな、と言うのを確認してみたいのですが……

    • ベストアンサー
    • PHP
  • テーブルごとのカウント

    PHP5.2+mysql 5.0.45で開発を行っております。 SQLに関する質問なのですが 以下のことが可能かどうかご教授いただきたく。 4つのテーブルがあります。 (例は適当です。項目の名称等は無視してください。) テーブルA ID Name Kana テーブルB ID NameID Pref City テーブルC ID NameID Tel Fax テーブルD ID NameID email CellPhone とします。 A.ID=1000の時各テーブルのレコード数が A:B:C:D=1:3:2:2となっています。 SQLの出力結果として A.ID A.Name A.Kana B.Count(ID) C.Count(ID) D.Count(ID) という、6項目を出力したいのですが 方法がわかりません。 試してみたのは select A.ID,A.Name,A.Kana,Count(B.ID),Count(C.ID),Count(D.ID) from A left join B on A.ID = B.NameID left join C on A.ID = C.NameID left join D on A.ID = D.NameID where A.ID = 1000 group by A.ID,A.Name,A.Kana ですが 結果、 A.ID = 1000 A.Name = Name A.Kana = Kana Count(B.ID) = 3 Count(C.ID) = 3 Count(D.ID) = 3 となってしまいます。 冷静に考えるとそうなんですが・・・ もしうまく結果を取得できる方法があればご教授いただきたく よろしくお願いいたします。

    • ベストアンサー
    • MySQL

専門家に質問してみよう