我有三种型号,Shop,Mall和Sale。A Mall has_many Shops,A Shop belongs_to a Mall and has_many Sales,a Sale belongs_to a Shop.我想要做的是,当我去一个特定的购物中心的show页面,我想让它,只有属于该特定购物中心的商店的销售出现在该页面(购物中心展示页面)。所以我尝试了很多不同的方法在商场管理员的表演动作中这样做,但是我不断地发现这个错误:
NilClass的未定义方法'sales‘
这是我的购物中心管理员:
class MallsController < ApplicationController
before_action :set_mall, only: [:show, :edit, :update, :destroy]
# GET /malls/1
# GET /malls/1.json
def show
@shops = @mall.shops.all
@sales = @shop.sales.where('offer_end >= ?', Date.today).order('discount_to DESC')
end
private
# Use callbacks to share common setup or constraints between actions.
def set_mall
@mall = Mall.find(params[:id])
end
endshop.rb:
class Shop < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
has_many :mall_shops
has_many :malls, :through => :mall_shops
has_many :sales, dependent: :destroy
validates :name, presence: true, uniqueness: true
endmall.rb
class Mall < ActiveRecord::Base
has_many :mall_shops
has_many :shops, :through => :mall_shops
validates :name, presence: true, uniqueness: true
endsale.rb:
class Sale < ActiveRecord::Base
belongs_to :shop
endmall_shop.rb
class MallShop < ActiveRecord::Base
belongs_to :shop
belongs_to :mall
end发布于 2016-03-07 15:56:19
这是行不通的:
def show
@shops = @mall.shops.all
@sales = @shop.sales.where('offer_end >= ?', Date.today).order('discount_to DESC')
end这里您定义了@shops,这是一组商店,然后在一个未定义的@shop变量上调用.sales。
但是,即使将变量更改为@shops,它也不会工作,因为.sales是Shop实例上的一个方法。
为了解决这个问题,我们希望在一次扫描中尽可能多地使用联接来加载。
首先,删除set_mall回调,因为我们需要对此操作的加载进行更细粒度的控制:
before_action :set_mall, only: [:edit, :update, :destroy]然后,在显示动作中,您要加载购物中心,并在一次扫描中加入相关记录。但是,在加载销售时,您可能需要执行单独的查询。
def show
@mall = Mall.eager_load(shops: :sales).find(params[:id])
@sales = Sale.joins(:shop)
.where(shop_id: @mall.shops.ids)
.where('offer_end >= ?', Date.today)
.order(discount_to: :desc)
end您希望在一个单独的查询中获取@sales的原因是,您需要执行一个LEFT OUTER连接,或者在第一个查询中没有销售就不能得到这些商店,如果您想单独列出它们,还需要遍历商店的集合来收集它们。
发布于 2016-03-07 15:46:47
您没有定义@shop,这就是为什么要获得undefined method 'sales' for nil:NilClass
https://stackoverflow.com/questions/35847564
复制相似问题