2

In my rails app, I am using jquery-datatables-rails. It works fine for single model. But if I have associated model then I don't know how to use sort_column function. My code is below0.

delegate :params, :h, :link_to, :image_tag, :edit_product_path, to: :@view

  def initialize(view)
    @view = view
  end

  def as_json(options = {})
    {
        sEcho: params[:sEcho].to_i,
        iTotalRecords: Product.count,
        iTotalDisplayRecords: products.total_entries,
        aaData: data
    }
  end

  private

  def data
[
          product.name,
          product.number,
          product.owner_email
      ]
  end

def products
    @products||= fetch_products
  end

  def fetch_products
    products= Product.order("#{sort_column} #{sort_direction}")
    products= products.page(page).per_page(per_page)
    if params[:sSearch].present?
      products= products.where("namelike :search", search: "%#{params[:sSearch]}%")
    end
    products
  end

  def page
    params[:iDisplayStart].to_i/per_page + 1
  end

  def per_page
    params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
  end

  def sort_column
    columns = %w[name number owner_email]
    columns[params[:iSortCol_0].to_i]
  end

  def sort_direction
    params[:sSortDir_0] == "desc" ? "desc" : "asc"
  end

My product.rb

class Product < ActiveRecord::Base
  delegate :email, to: :owner, allow_nil: true, prefix: true
  belongs_to :owner, :class_name => "Owner"

as you can see, in sort_column method I am using owner.email since in data method I have product.owner.email. But this does not sort the table. I think this is not the correct way to use it. Here product and owner are two different model with has_many relationship. Please let me know how can I make it work.

1 Answer 1

1
products= Product.order("#{sort_column} #{sort_direction}")

This is where the sorting happens. If the sort_column is owner.email then you need owners table to be preloaded alongside with the products table. So you need this joins:

products= Product.joins(:owner).order("#{sort_column} #{sort_direction}")

and plural name in sort_columns:

columns = %w[name number owners.email]

But we don't need to load owners table when sorting is done for name and number columns. To solve this problem it's better to define a method that returns relation name by search column name:

def joins_relation(column)
  case column
  when 'owners.email'
    :owner
  else
    nil
  end
end

And use it like this:

products= Product.joins(joins_relation(sort_column)).order("#{sort_column} #{sort_direction}")
Sign up to request clarification or add additional context in comments.

5 Comments

Did you add this code to Product model? And did you change product.owner.email to product.owner_email in data?
sorry! what do I have to add in my product model? I did not add anything in product model
The one-line code from my answer. It allows you to call product.owner_email instead of product.owner.email. You also need to correctly specify column name during datatables initialization, so that iSortCol_0 param include owner_email value for the corresponding column.
Please have a look at my updated question with your given changes. But still not working
Ok, I'm sorry, my answer is wrong. I didn't pay much attention to the code. Revert the changes and see the updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.