Search code examples
ruby-on-railsrubyruby-on-rails-4before-filter

Why doesn't before_filter apply to filter list of displayed products ? (rails4)


I have a simple homepage with a list of Deals.

I'd like to filter this list by country using before_filter.

Here is my code on /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

But it does not work: on my screen, I see also deals which are not from the United States

It's like the first before filter where I try to set 'only United states country' is overriden by my method "home" that comes after.

Hers is what I get on my console:

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)

For the sake of reference here is the method featured_on_hp, I used (but it has no impact here I think):

app/models/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) }

How can I tell Rails to first apply the before_filter and only take deals from the United States, and only then apply the method home and get among these US deals those who should be featured today ?

thanks

PS: of course when this problem is solved I will replace "united states" by a variable holding the name of the countries i want


Solution

  • I'd do:

    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
    

    Your before_filter is pointless here. If you need to use a particular scope somehow, just write it explicitly.