具有has_many has_many关联的Eagerload对象,其中并非所有关联都存在

时间:2016-05-02 14:38:27

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我有2个模型:具有many_to_many关系的Deal和User以及user_deal连接表。

在主页上,我会显示优惠列表。对于我在user_deal表中的view n属性中使用的每个Deal。

我怎样才能加载这个?

我试着这样做:

主页控制器

def home    

    @deals = Deal.includes(:user_deals) 

    respond_to do |format|
      format.html # home.html.erb
      format.json { render json:  @deals }
      format.xml  { render xml:   @deals }
      # format.atom
    end

  end
end

模型

class Deal < ActiveRecord::Base
  has_many   :user_deals,           dependent:  :destroy
  has_many   :users,                through:    :user_deals
end

class User < ActiveRecord::Base
  has_many :user_deals          
  has_many :deals,                through: :user_deals
end

class UserDeal < ActiveRecord::Base
  belongs_to :user,         :foreign_key => 'user_id'
  belongs_to :deal,         :foreign_key => 'deal_id'
end

但是我觉得它不起作用,因为它预先加载东西,然后第二次加载每个对象......

Processing by StaticPagesController#home as HTML
   (0.5ms)  SELECT COUNT(*) FROM "Deals" AND "Deals"."featured" = 't' 
  Deal Load (0.7ms)  
SELECT "Deals".* FROM "Deals" WHERE "Deals"."country" = $1 AND  "Deals"."featured" = 't' ORDER BY "Deals"."Deal_end_date" ASC

 // it seems here below to implement the preloading
UserDeal Load (1.2ms)  SELECT "user_deals".* FROM "user_Deals" WHERE "user_Deals"."Deal_id" IN (30, 339, 341, 337, 353, 31, 354, 260)

//but then it's loading things individually again  
UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 30) LIMIT 1
  UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 339) LIMIT 1
  UserDeal Load (0.7ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 341) LIMIT 1
  UserDeal Load (0.7ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 337) LIMIT 1
  UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 353) LIMIT 1
  UserDeal Load (0.7ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 31) LIMIT 1
  UserDeal Load (0.9ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 354) LIMIT 1
  UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 260) LIMIT 1

我对问题来自何处的假设(我不确定)

问题可能出在User_deal表中。它以这种方式工作:如果用户参与交易,则创建一个新行,其中user_id = 5,deal_id = 4,number_of_participations = 6 因此,如果用户4从未参与过交易7,则没有行user_id = 4和deal_id = 7

所以在主页上,Rails去获取交易列表:交易1,交易2 ......交易7。 但他没有找到deal_7所在的行,因为没有这样的行。

理想情况下,我应该告诉Rails包含(:user_deals)但只包括那些在连接表UserDeals里面的那些user_id = current_user.id或其中user_id = current_user.id的行不存在...我没有经理无论如何要实施

但我是一名RoR新秀,所以我不确定我上面的想法

修改

根据建议尝试eager_load而不是包含,我得到:

    User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 625]]
    Processing by StaticPagesController#home as HTML
       (0.7ms)  SELECT COUNT(DISTINCT "deals"."id") FROM "deals" LEFT OUTER JOIN "user_deals" ON "user_deals"."deal_id" = "deals"."id" WHERE "deals"."country" = $1 AND (deal_launch_date <= '2016-05-02 17:21:59.547029' AND deal_end_date >= '2016-05-02 17:21:59.547087') AND "deals"."featured" = 't'  [["country", "France"]]
      SQL (3.0ms)  SELECT "deals"."id" AS t0_r0, "deals"."country" AS t0_r1, "deals"."title" AS t0_r2, "deals"."deal_card_edito" AS t0_r3, "deals"."twitter_msg" AS t0_r4, "deals"."image_url" AS t0_r5, "deals"."prelaunch_date" AS t0_r6, "deals"."featured" AS t0_r9, "deals"."admin_user_id" AS t0_r10, "deals"."created_at" AS t0_r11, "deals"."updated_at" AS t0_r12,........................................................................................................
"user_deals"."id" AS t1_r0, "user_deals"."user_id" AS t1_r1, "user_deals"."deal_id" AS t1_r2, "user_deals"."number_participations" AS t1_r3, "user_deals"."nb_new_clicks" AS t1_r4, "user_deals"."created_at" AS t1_r5, "user_deals"."updated_at" AS t1_r6 FROM "deals" LEFT OUTER JOIN "user_deals" ON "user_deals"."deal_id" = "deals"."id" WHERE "deals"."country" = $1 AND (deal_launch_date <= '2016-05-02 17:21:59.547029' AND deal_end_date >= '2016-05-02 17:21:59.547087') AND "deals"."featured" = 't'  ORDER BY "deals"."deal_end_date" ASC  [["country", "France"]]
      UserDeal Load (0.9ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 30) LIMIT 1
      UserDeal Load (1.0ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 339) LIMIT 1
      UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 341) LIMIT 1
      UserDeal Load (0.6ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 337) LIMIT 1
      UserDeal Load (0.9ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 353) LIMIT 1
      UserDeal Load (1.0ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 31) LIMIT 1
      UserDeal Load (0.5ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 354) LIMIT 1
      UserDeal Load (0.9ms)  SELECT  "user_deals".* FROM "user_deals" WHERE (user_id = 625 AND deal_id = 260) LIMIT 1

0 个答案:

没有答案