2017-03-16 6 views
1

に参加してAREL :: SelectManagerからアクティブ関係= = 'カール'。 (アクティブレコードが参加したが、これは単純な例を維持することであると、この場合、私たちは幸せである可能性があります。)AREL:私たちはのRails 4.2.xではアプリを持っているし、我々は二つのテーブルの投稿や著者を持っている、と私たちは名前を持つ著者が執筆記事を取得するためにARELを使用したい私たちをみましょう

posts = Arel::Table.new :posts 
authors = Arel::Table.new :authors 

my_query = posts.project(Arel.star) 
       .join(authors) 
       .on(posts[:author_id].eq(authors[:id])) 
       .where(authors[:name].eq('Karl')) 

> my_query.class 
=> Arel::SelectManager 

今、私たちがやっによってポストの(クラスArrayの)配列を取り戻すことができます:

> Post.find_by_sql my_query 
[master] Post Load (3.1ms) SELECT * FROM "posts" INNER JOIN "authors" 
          ON "posts"."author_id" = "authors"."id" 
          WHERE "authors"."name" = 'Karl' 

=> [#<Post:0x005612815ebdf8 
    id: 7474, 
    ... 
    ] 

だから我々はポストの配列を得るか、いないアクティブなレコードの関係:

> Post.find_by_sql(my_query).class 
=> Array 

またPost.whereにマネージャーが

01を動作しません注入
> Post.where my_query 
=> #<Post::ActiveRecord_Relation:0x2b13cdc957bc> 
> Post.where(my_query).first 
ActiveRecord::StatementInvalid: PG::SyntaxError: 
ERROR: subquery must return only one column 
SELECT "posts".* FROM "posts" 
WHERE ((SELECT * FROM "posts" INNER JOIN "authors" ON "posts"."author_id" = "authors"."id" WHERE "authors"."name" = 'Karel')) 
ORDER BY "posts"."id" ASC LIMIT 1 

私は何かが欠けする必要があります考えています。要するに:あなたはどのように上記のmy_query(または同じことを達成する別の選択マネージャ)のような選択マネージャからアクティブなレコードの関係を取得します。

答えて

2

あなたはActiveRecordの:: AREL :: SelectManagerからどちらのSQL文字列から関係を取得することはできません。 ActiveRecordでデータをロードするには、次の2つの方法があります。

  1. Arelのすべてのクエリロジックを実行します。この場合、ActiveRecord :: Relationメソッドは使用できません。しかし、あなたはArelで同じ機能を持っています。あなたの例では、ARELを通じて制限を設定することがあります。

    my_query.take(10) 
    
  2. その他の方法は、ActiveRecordの::関連法にARELを使用することです。あなたはActiveRecordのようmy_query使用することができます。この場合

    posts = Arel::Table.new :posts 
    authors = Arel::Table.new :authors 
    
    join = posts.join(authors). 
          on(posts[:author_id].eq(authors[:id])). 
          join_sources 
    
    my_query = Post. 
           joins(join). 
           where(authors[:name].eq('Karl')) 
    
    > my_query.class 
    => ActiveRecord::Relation 
    

::関係

:あなたはこのようなあなたのクエリを書き直すこと
関連する問題