Reputation: 747
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
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