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 Answers1

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}")
Jeiwan
  • 954
  • 6
  • 13
  • 1
    Did you add this code to Product model? And did you change `product.owner.email` to `product.owner_email` in `data`? – Jeiwan Dec 28 '15 at 14:31
  • 1
    sorry! what do I have to add in my product model? I did not add anything in product model –  Dec 28 '15 at 14:36
  • 1
    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. – Jeiwan Dec 28 '15 at 14:55
  • Please have a look at my updated question with your given changes. But still not working –  Dec 28 '15 at 15:10
  • 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. – Jeiwan Dec 28 '15 at 15:28