为什么before_filter不适用于显示产品的过滤列表? (rails4)

时间:2014-06-14 10:08:28

标签: ruby-on-rails ruby ruby-on-rails-4 before-filter

我有一个简单的主页,上面有一系列优惠。

我想使用before_filter按国家/地区筛选此列表。

这是我在/app/controllers/static_pages_controller.rb上的代码

class StaticPagesController < ApplicationController

  before_filter :filter_deals_based_on_visitor_country,
    :only => [ :home]  


  def filter_deals_based_on_visitor_country
    @deals = Deal.find_by(:country => "United States") 
  end    

  def home          
    @deals = Deal.featured_on_hp.to_a

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

end

但它不起作用:在我的屏幕上,我也看到了不是来自美国的交易

它就像过滤器之前的第一个,我试图设置“只有美国国家/地区”。被我的方法覆盖&#34; home&#34;之后。

她是我在我的控制台上获得的:

Started GET "/" for 127.0.0.1 at 2014-06-14 12:00:22 +0200
Processing by StaticPagesController#home as HTML
  Deal Load (0.7ms)  SELECT "deals".* FROM "deals" WHERE "deals"."country" = 'United States' LIMIT 1
  Deal Load (0.7ms)  SELECT "deals".* FROM "deals" WHERE (deal_launch_date <= '2014-06-14 12:00:22.522089' AND deal_end_date >= '2014-06-14 12:00:22.522116') AND "deals"."featured" = 't' ORDER BY deals.created_at DESC
  Rendered layouts/_hp_deal_card.html.erb (5.2ms)
  Rendered static_pages/home.html.erb within layouts/application (317.7ms)
  Rendered layouts/_metas.html.erb (0.1ms)
  Rendered layouts/_navigation.html.erb (1.7ms)
  Rendered layouts/_header.html.erb (3.0ms)
  Rendered layouts/_messages.html.erb (0.1ms)
  Rendered layouts/_footer.html.erb (0.6ms)
Completed 200 OK in 351ms (Views: 346.7ms | ActiveRecord: 1.5ms)

为了便于参考,这里是我使用的方法feature_on_hp(但我觉得它没有影响):

应用程序/模型/ deal.rb

scope :featured_on_hp,lambda { default.where('deal_launch_date <= ? AND deal_end_date >= ?', Time.zone.now, Time.zone.now).where(featured: true) }

我如何告诉Rails首先应用before_filter并且只接受来自美国的交易,而只有将该方法应用于主页并在这些美国交易中获取今天应该被推荐的人? / p>

感谢

PS:当然,当这个问题解决后,我将取代&#34;美国&#34;通过一个包含我想要的国家名称的变量

2 个答案:

答案 0 :(得分:1)

我做:

class StaticPagesController < ApplicationController

  def home          
    @deals = scope.featured_on_hp

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

  private

  def scope
    Deal.where(:country => "United States") 
  end    
end

你的before_filter在这里毫无意义。如果你需要以某种方式使用特定的范围,只需明确地写它。

答案 1 :(得分:1)

before_filter无法正常工作的原因是,它会在@deals行动中再次指定home,然后您覆盖,撤消您所做的任何事情在before_filter

我会在你的模型上添加一个for_country方法,它返回一个ActiveRecord :: Relation

class Deal < ActiveRecord::Base

  def self.for_country(country)
    where(country: country)
  end

end

然后在你的控制器中你可以写

def home          
  @deals = Deal.for_country(params[:country] || "United Stated").featured_on_hp

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

这当然是假设您在params上指定国家/地区(如果您通过url或参数执行此操作,它将会执行。)

注意我永远不会添加明确的to_a调用。