matiss
matiss

Reputation: 747

Rails 5.1.: cannot get JSON object from string

I'm a bit stuck with JSON parsing as I'm new to coding and this is my first time dealing with JSON :) I kind of figured out how to save JSON, but can't read it back from DB.

I have this Controller:

class Common::DatatablesStatesController < ApplicationController

  require 'json'

  def update
    datatables_state.update(datatable_states_params)
    render json: datatables_state
  end

  def show
    table_state = current_user.datatables_states.where(name: params[:id]).select(:state)
    state = JSON.parse(table_state)
    render json: { state: state["state"] }
  end

  private

  def datatable_states_params
    params['common_datatable_state']['state'] = params['common_datatable_state']['state'].to_json
    params.require(:common_datatable_state).permit(:user_id, :name, :state)
  end

  def datatables_state
    @datatables_state ||= current_user.datatables_states.where(name: params[:id]).first_or_create
  end
end

In terminal I see my Update action is working, however I cannot make Show action to work as it throws out this error:

TypeError (no implicit conversion of Common::DatatableState::ActiveRecord_AssociationRelation into String):    
app/controllers/common/datatables_states_controller.rb:12:in `show'
app/controllers/application_controller.rb:41:in `set_current_user'

In my Pry I can do this:

[3] pry(main)> user.datatables_states.where(name: 'campaigns_index').select(:state)
  Common::DatatableState Load (0.5ms)  SELECT "common_datatable_states"."state" FROM "common_datatable_states" WHERE "common_datatable_states"."user_id" = $1 AND "common_datatable_states"."name" = $2  [["user_id", 2], ["name", "campaigns_index"]]
=> [#<Common::DatatableState:0x000000028e3f30
  id: nil,
  state:
   "{\"time\":\"1494910215056\",\"start\":\"0\",\"length\":\"10\",\"order\":{\"0\":[\"0\",\"asc\"]},\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"},\"columns\":{\"0\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"1\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}},\"2\":{\"visible\":\"true\",\"search\":{\"search\":\"\",\"smart\":\"true\",\"regex\":\"false\",\"caseInsensitive\":\"true\"}}}}">]

How do I get single JSON object from string I have in state field (JSON column, Postgres) from my DB, please? Thank you!

Update

This piece of code from application_controller.rb helped to access current_user outside Controllers:

#38    around_action :set_current_user
#39      def set_current_user
#40        Current.user = current_user
#41        yield
        ensure
          Current.user = nil
        end

Update 2

After I updated show to this:

def show
  table_state = current_user.datatables_states.where(name: params[:id]).select(:state).first
  state = JSON.parse(table_state.state)
  render json: { state: state }
end

I still don't see it loading my state drom DB with stateLoadCallback from JS below:

jQuery(document).ready(function() {
  var user_id = $("#data-table").attr('data-user-id');
  var contname = $("#data-table").attr('data-controller-name');
    $('#data-table').DataTable(
            {
                "processing": true,
                "serverSide": true,
                "ajax": $('#data-table').data('source'),
                stateSave: true,
                "stateSaveCallback": function (settings, data) {
                    // Send an Ajax request to the server with the state object
                    $.ajax( {
                        "url": "/common/datatables_states/"+contname+".json",
                        "data": {"common_datatable_state":{"user_id": user_id, "name": contname, "state": data}} ,
                        "dataType": "json",
                        "type": "PATCH",
                        "success": function () {}
                    } );
                },
                   stateLoadCallback: function (settings, callback) {
                      $.ajax( {
                         url: '/common/datatables_states/'+contname+'.json',
                         async: false,
                         dataType: 'json',
                         type: 'GET',
                         success: function (json) {
                         callback( json );
                         }
                    } );
                 }
            }
    );
});

Upvotes: 2

Views: 532

Answers (1)

JCorcuera
JCorcuera

Reputation: 6834

The problem is that table_state is an ActiveRecord::Relation of Common::DatatableState as you point in your example. You are trying to parse the relation which is not a string.

What about this:

table_state = current_user.datatables_states.where(name: params[:id]).select(:state).first
state = JSON.parse(table_state.state)
render json: { state: state }

Upvotes: 1

Related Questions