Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Active record query issues in Rails 3.2

I have category model and category has many postings.

Problem: Sometimes postings are not visible under category in web even records are present in database

I investigated the query for the action in production enviroment by enabling config.log_level = :debug and restarted the nginx passenger server. Now I can see the records under the category. I was unable to reproduce the same issue again and it occurs rarely.

Note:

  1. I didn't change any code in the project. The same code behave differently.
  2. Rails is 3.2.22. Nginx passenger(5.1.1)

Model are as follows

class Category < ActiveRecord::Base
  has_many :postings, conditions: ['paid = ? AND start_date <= ? AND end_date >= ?', true, Date.current, Date.current]
end

class Posting < ActiveRecord::Base
  searchkick

  belongs_to :category

  class << self

    def payed
      where paid: true
    end

    def activated
     where :code => ""
    end

    def starts_on(date)
      where "start_date <= ?", date
    end

    def ends_after(date)
      where "end_date >= ?", date
    end

    def in_location(state,city)
      where(stateid: state.id, cityid: city.id)
    end

    def not_deleted
      where "active != false"
    end
end

Postings controller

def index
  @category = Category.find(params[:category_id])
  postings = @category.postings.payed.activated.not_deleted.starts_on(Date.current).ends_after(Date.current).order(:created_at)
  @postings = postings.in_location(current_state, current_city).page(params[:page])
end

From production.log, when accessing postings page /postings?category_id=25

Category Load (0.2ms) SELECT categories.* FROM categories WHERE categories.id = 25 LIMIT 1

(0.4ms) SELECT COUNT(*) FROM postings WHERE postings.category_id = 25 AND postings.paid = 1 AND postings.code = '' AND postings.stateid = 44 AND postings.cityid = 14823 AND (active != false) AND (paid = 1 AND listing_start_date <= '2017-03-13' AND listing_end_date >= '2017-03-13') AND (listing_start_date <= '2017-03-13') AND (listing_end_date >= '2017-03-13')

CACHE (0. SELECT COUNT(*) FROM postings WHERE postings.category_id = 25 AND postings.paid = 1 AND postings.code = '' AND postings.stateid = 44 AND postings.cityid = 14823 AND (active != false) AND (paid = 1 AND listing_start_date <= '2017-03-13' AND listing_end_date >= '2017-03-13') AND (listing_start_date <= '2017-03-13') AND (listing_end_date >= '2017-03-13')

Posting Load (0.4ms) SELECT postings.* FROM postings WHERE postings.category_id = 25 AND postings.paid = 1 AND postings.code = '' AND postings.stateid = 44 AND postings.cityid = 14823 AND (active != false) AND (paid = 1 AND listing_start_date <= '2017-03-13' AND listing_end_date >= '2017-03-13') AND (listing_start_date <= '2017-03-13') AND (listing_end_date >= '2017-03-13') ORDER BY created_at LIMIT 10 OFFSET 0

The above set of queries did not pick any records; and after enabling debug mode and restart/touch the nginx server the same query fetched available records

Is the problem caused by active record query/ Nginx/ cache?

Please help me to resolve this issue.

like image 442
Manivannan Jeganathan Avatar asked Mar 13 '17 09:03

Manivannan Jeganathan


People also ask

What is ActiveRecord query Interface in rails?

Active Record insulates you from the need to use SQL in most cases. Active Record will perform queries on the database for you and is compatible with most database systems, including MySQL, MariaDB, PostgreSQL, and SQLite.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.

What is active record pattern in rails?

The active record pattern is an approach to accessing data in a database. A database table or view is wrapped into a class. Thus, an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database.

What is ActiveRecord base?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.


1 Answers

Fixed the problem using Proc for association condition like

has_many :postings, conditions: proc { "payed = 1 AND start_date <= '#{Date.current.to_s(:db)}' AND end_date >= '#{Date.current.to_s(:db)}'"}

If you would have done association with dynamic condition like has_many :postings, conditions: ['paid = ? AND start_date <= ? AND end_date >= ?', true, Date.current, Date.current], there will be cases when the results you’ll get are not expected since the condition will have the day you started the Rails application and Date.current won’t be called again.

Thanks to Jose M.Gilgado. Reference: http://josemdev.com/articles/dynamic-conditions-associations-rails-3/

like image 64
Manivannan Jeganathan Avatar answered Oct 09 '22 18:10

Manivannan Jeganathan