我有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