jbox-web / ajax-datatables-rails

A wrapper around DataTable's ajax methods that allow synchronization with server-side pagination in a Rails app
MIT License
590 stars 227 forks source link

Using in API only mode? #240

Closed mrudult closed 7 years ago

mrudult commented 7 years ago

I'm trying to use this in API only mode with Rails - 4.2.8, rails-api (0.4.1), ajax-datatables-rails (0.4.0)

When I try to hit the url via curl it only prints the datatable's object. Here's the datatable class:

class UserDatatable < AjaxDatatablesRails::Base

  def view_columns
    @view_columns ||= {
      first_name: { source: "User.first_name" },
      last_name: { source: "User.last_name" },
      email: { source: "User.email" }
    }
  end

  def data
    records.map do |record|
      {
        first_name: record.first_name,
        last_name: record.last_name,
        email: record.email
      }
    end
  end

  private

  def get_raw_records
    User.all
  end

end

The controller

def index
    respond_to do |format|
      format.json { render json: UserDatatable.new(view_context) }
    end
end

When I hit the url /app/users.json it just gives "#<UserDatatable:0x007f92b89a4d70>" as output.

I tried this in a non-api project (by directly doing a curl on the url) and it works fine (even in the html.erb templates everything works) with an output like:

{
    "draw": 0,
    "recordsTotal": 1,
    "recordsFiltered": 1,
    "data": [
        [
            "John",
            "Doe",
            "app@example.com"
        ]
    ]
}

What am I possibly doing wrong here? I'm essentially trying to use this gem for server side processing and using JQuery Datatable with AngularJs as front-end.

n-rodriguez commented 7 years ago

Can you please try with :

def index
    respond_to do |format|
      format.json { render json: UserDatatable.new(view_context).to_json }
    end
end
mrudult commented 7 years ago

@n-rodriguez Same output.

ajahongir commented 7 years ago

what if?

def index
  render json: UserDatatable.new(view_context)
end
mrudult commented 7 years ago

@ajahongir Same output.

ajahongir commented 7 years ago

well. try this?

def index
  data = {id: 1, name: 'test'}
  render json: data
end
mrudult commented 7 years ago

@ajahongir works as expected

{
    "id": 1,
    "name": "test"
}
ajahongir commented 7 years ago

so this also not working?

def index
  render json: UserDatatable.new(view_context).to_json
end

did you override to_json method on your datatable?

mrudult commented 7 years ago

@ajahongir Nope. That doesn't work. I didn't override to_json method. Though, as I'm using rails-api with the following gems:

gem 'oj'
gem 'oj_mimic_json'
gem 'jbuilder'

My guess is that, this has something to do with views (view_context) as it works fine with normal non-api based projects.

antillas21 commented 7 years ago

Not sure if view_context works in a API mode, as there is no view provided.

[image: --]

José Antonio Antillón [image: http://]about.me/aantillon http://about.me/aantillon?promo=email_sig

On Mon, Jul 17, 2017 at 12:08 AM, Mrudul Tarwatkar <notifications@github.com

wrote:

@ajahongir https://github.com/ajahongir Nope. That doesn't work. I didn't override to_json method. Though, as I'm using rails-api with the following gems:

gem 'oj' gem 'oj_mimic_json' gem 'jbuilder'

My guess is that, this has something to do with views (view_context) as it works fine with normal non-api based projects.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jbox-web/ajax-datatables-rails/issues/240#issuecomment-315681393, or mute the thread https://github.com/notifications/unsubscribe-auth/AAUXZ3gu9vZyCKA2c7re-y3GRqCL1SNhks5sOwh2gaJpZM4ONsFN .

matissg commented 7 years ago

@mrudult I might be wrong, but isn't it about passing record ID to Datatables? I'm using Datatables Editor and in my Index view I'm populating HTML only for opening Index page, then later JSON is used for CRUD. For Editor, here is info, how you customize DT_RowId.

mrudult commented 7 years ago

@matissg Not sure. As I said, my configuration works fine in a non-api based project without passing the record ID. I think it's because of the view_context. Need to figure it out.

Any help will be highly appreciated.

n-rodriguez commented 7 years ago
NameError (undefined local variable or method `view_context' for #<PostsController:0x0000000286d998>
Did you mean?  view_runtime):
n-rodriguez commented 7 years ago

The solution :

In routes.rb :

Rails.application.routes.draw do
  resources :posts do
    post 'datatable', on: :collection
  end
end

In controller :

  def datatable
    render json: PostsDatatable.new(params)
  end

In datatable :

class PostsDatatable < AjaxDatatablesRails::Base

  # the trick starts here
  attr_reader :params

  def initialize(params, options = {})
    @params  = params # this is what we're looking for, so don't rename it
    @options = options
    load_orm_extension
  end
  # the trick ends here

  def view_columns
    @view_columns ||= {
      title:   { source: 'Post.title' },
      content: { source: 'Post.content' },
    }
  end

  def data
    records.map do |record|
      {
        title:   record.title,
        content: record.content,
        'DT_RowId' => record.id,
      }
    end
  end

  def get_raw_records
    Post.all
  end

end

The test :

#!/usr/bin/env ruby

require 'json'
require 'yaml'
require 'rest-client'

params =
    {
      'draw' => '1',
      'columns' => {
        '0' => {
          'data' => 'title', 'name' => '', 'searchable' => 'true', 'orderable' => 'true',
          'search' => {
            'value' => '', 'regex' => 'false'
          }
        },
        '1' => {
          'data' => 'content', 'name' => '', 'searchable' => 'true', 'orderable' => 'true',
          'search' => {
            'value' => '', 'regex' => 'false'
          }
        },
      },
      'order' => {
        '0' => {'column' => '0', 'dir' => 'asc'}
      },
      'start' => '0', 'length' => '10', 'search' => {
        'value' => '', 'regex' => 'false'
      },
      '_' => '1423364387185'
    }

response = RestClient.post('http://localhost:3000/posts/datatable.json', params)
json = JSON.load(response.body)
puts YAML::dump(json)

The result :

---
recordsTotal: 20
recordsFiltered: 20
data:
- title: amet fuga at
  content: Qui tempore sapiente recusandae. Adipisci reprehenderit quo nihil harum
    praesentium maiores. Ipsum ullam rerum occaecati cupiditate ex est. Ipsam velit
    suscipit. Aut est laboriosam quia.
  DT_RowId: '34'
- title: blanditiis corrupti vel
  content: Beatae nisi recusandae eligendi aut omnis. Illo unde quam iste quia maiores
    voluptatem. Modi a consequatur voluptatum eos.
  DT_RowId: '24'
- title: dolore necessitatibus cumque
  content: Sit possimus placeat. Sit tenetur enim suscipit quis. Porro natus voluptas
    et sit iste reiciendis ab. Ut et cumque molestiae impedit nemo.
  DT_RowId: '31'
- title: dolorum voluptas vel
  content: Repellat iusto cupiditate qui. Dolor voluptatum nulla nisi vel quis laudantium
    ut. Vitae nulla dicta rerum.
  DT_RowId: '29'
- title: ea nihil laudantium
  content: Ipsa ut corrupti et non. Quaerat aliquid non ullam. Architecto consequatur
    quos temporibus.
  DT_RowId: '37'
- title: esse consequuntur nisi
  content: Repudiandae voluptas nostrum excepturi et quos beatae. Placeat sed aut
    voluptatem porro iure dolores. Optio voluptas possimus qui libero eum. Odit tempore
    excepturi praesentium exercitationem non expedita. Porro quam nemo voluptate.
  DT_RowId: '23'
- title: esse optio aspernatur
  content: Dolorum quisquam sequi ut aspernatur provident sunt. Quod aut consequuntur
    voluptas et rem eveniet et. Tempore labore qui ipsum dolorem adipisci fugiat.
  DT_RowId: '36'
- title: et qui officiis
  content: Provident corporis occaecati dignissimos doloremque. Dicta quidem ea est
    perspiciatis dolores. Non qui sit distinctio quam qui vel. Aspernatur neque quia
    sit.
  DT_RowId: '32'
- title: fuga ut facere
  content: Quam qui voluptatem. Aliquid praesentium doloribus harum veniam. Eum accusamus
    sapiente maxime quaerat. Porro voluptatibus optio alias non labore quia voluptas.
  DT_RowId: '33'
- title: fugiat recusandae est
  content: Facere commodi sed minima. Alias exercitationem consequatur est ut voluptatem
    ipsum dolorem. Dignissimos sequi consequatur ut. Nostrum debitis maiores fugit
    ut repellendus inventore.
  DT_RowId: '22'
mrudult commented 7 years ago

@n-rodriguez Nah. Still the same output. I don't get the undefined local variable or methodview_context' ` error either.

I'm gonna try and reproduce this tomorrow.

Thanks

mrudult commented 7 years ago

After digging deeper, the oj_mimic_json gem was the culprit. I guess, it was calling the to_json method twice - once in datatable and again in controller.

However, I'm getting the same issue as this when upgrading to v0.4.0. Downgrading to v0.3.1 works.

Rails - 4.2.8, rails-api (0.4.1), ajax-datatables-rails (0.4.0)