Use JSON result in query using Ruby, Sinatra and PostgreSQL - ruby

I am using Ruby and the Plivo api to create a subaccount.
The code is:
AUTH_ID = "my_id"
AUTH_TOKEN = "my_token"
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {'name' => 'thegreatone'}
response = p.create_subaccount(params)
// up to here is fine and (without my attempts below to access the json response) it works and the account is created.
The JSON response is :
[{"auth_token"=>"ZjgxMGQwMTY2NGY3Nzk3ZmM3ZGE3ZmIxMGQyZWYy",
"message"=>"created",
"api_id"=>"2c1eff4a-b955-11e2-8361-123141011ae6",
"auth_id"=>"SAMZBJOGZKZDIXMMEXNJ"}]
I would like to "extract" the "auth_token" and "auht_id" so that I can insert them into my database.
So I have tried (among other things):
obj = JSON.parse(response)
:user_key = obj['auth_token']
the message in my terminal is:
syntax error, unexpected '=', expecting $end
:user_key = obj['auth_token']
How can I extract these variables and then pass them to my insert query?
I am using postgres with SEQUEL, ruby and sinatra.

You're trying to assign a value to a symbol and the response returns an array:
obj = JSON.parse(response)
:user_key = obj['auth_token']
should be
obj = JSON.parse(response).first
user_key = obj['auth_token']
symbols are not variables, they are constants.

The response is an array containing the code response and then the data, so your code should be
obj = JSON.parse(response).last
user_key = obj['auth_token']
Edit: Turns out the gem already do the parse for you plivo.rb. So the code would be:
obj = response.last
user_key = obj['auth_token']

Related

Update hash with Rails 4

I have an hash object:
#chosen_opportunity = {"id"=>66480, "prize_id"=>4, "admin_user_id"=>1, "created_at"=>2015-09-20 18:37:29 +0200, "updated_at"=>2015-09-20 18:37:29 +0200, "opportunity_available"=>true}
How do I update the value of deal_available to false?
I tried this but it fails:
#chosen_opportunity['deal_available'] = false
#chosen_opportunity.save
controllers/deal_controller.rb:
def show_opportunity
#deal = Deal.friendly.find(params[:id])
#chosen_opportunity = Opoortunity.find_by_sql(
" SELECT \"opportunities\".*
FROM \"opportunities\"
WHERE (deal_id = #{#deal.id}
AND opportunity_available = true)
ORDER BY \"opportunities\".\"id\" ASC LIMIT 1"
)
# comes from http://apidock.com/rails/ActiveRecord/Base/find_by_sql/class
#chosen_opportunity[0].attributes['opportunity_available'] = false
#chosen_opportunity[0].save
respond_to do |format|
format.js
end
end
Can I update the value of opportunity_available from the Opportunity model inside a Deal controller? Is that why it's not working?
I know I could use Active Record but I need to use raw PostgreSQL for the first query. Thanks for your understanding of this non very Rails-y way.
You can change your code to:
#chosen_opportunity = Opportunity.find_by deal_id: deal.id, opportunity_available: true
#chosen_opportunity.opportunity_available = false
#chosen_opportunity.save!
This is much more Rails compatible. In addition, if I'm not mistaken, Rails won't let you save an object that you got through find_by_sql, so at the least you'd need to get a proper model object from the result. You can write (very ugly) code like:
Opportunity.where(id: #chosen_opportunity[0].attributes['id'])
.update_all(opportunity_available: false)
Warning: This will update the database, but not the #chosen_opportunity[0] object.
There is no method save on a hash. You have to do it on the model that holds that hash as an instance variable.

How to convert cqlengine resultset objects into JSON format

I am writing an API which queries a Cassandra 2.1.2 based database and returns results in JSON format. I am using cqlengine for this.
Here is the simplified schema -
class Checkins(Model):
Model.__comment__ = "Table mapping for submit datastore"
changelist = columns.Integer (primary_key= True) # Changelist number
checkin_date = columns.DateTime() # Submit time
stream_name = columns.Ascii (primary_key= True) # Stream-name
creator = columns.Ascii () # Creator
My query is this
clobj = Checkins.objects(changelist=changelist).get()
How do I convert the resultset into a json format ?
You can create dictionaries from models as of cqlengine 0.12. From there you can use the json module to get a JSON format. You do have to be careful because datetimes are not json serializable. Therefore you will need to convert it to a string first (Or look at this question for other ways to fix the datetime serialization problem).
import json
clobj = Checkins.objects(changelist=changelist).get()
clobj_dict = dict(clobj_dict)
clobj_dict['checkin_date'] = str(clobj_dict['checkin_date'])
json_string = json.dumps(clobj_dict)
or you could add it as a property on the class
import json
class Checkins(Model):
# Define your model as before
# ...
#property
def json(self):
# Perform the same thing as before.
json_dict = dict(self)
json_dict['checkin_date'] = str(json_dict['checkin_date'])
return json.dumps(clobj_dict)
# Just call the property.
clobj = Checkins.objects(changelist=changelist).get()
json_string = clobj.json

How to save a set of things over and over (autosave)

I am creating a set of things (each thing has FK to the set) directly with forms. The problem I am having is with the view(s).
I want to create the set for the things and then update all the things over and over using AJAX (Kind of like autosave). In my case the set is a SurveySet and the thing is a Survey.
def screen_many(request):
if not request.is_ajax():
# get an ordered QuerySet of students
students = ids_to_students(request.GET.items())
e_students = ids_to_students(request.GET.items(), 'e')
i_students = ids_to_students(request.GET.items(), 'i')
survey_count = len(students)
# Build a dataset of students with there associated behavior types.
data = [{'student':s.pk, 'behavior_type': 'E'} for s in e_students]
data += [{'student':s.pk, 'behavior_type': 'I'} for s in i_students]
# Use that dataset as initial data for a formset
SurveyFormset = formset_factory(SurveyForm, extra=0)
survey_formset = SurveyFormset(initial=data)
# ... not shown: customizing the crispy form helper
# Make a new survey set...
ss = SurveySet()
ss.user=request.user
ss.save()
if request.is_ajax():
surveyset = get_object_or_404(SurveySet, pk=ss.pk)
surveys = surveyset.survey_set.all()
survey_formset = SurveyFormset(request.POST, instance=surveyset)
if survey_formset.is_valid():
# Create surveys for this surveyset
for form in survey_formset.forms:
saved = form.save(commit=False)
saved.surveyset = ss
saved.save()
HttpResponse('saved.')
formsetWithStudents = zip(survey_formset.forms, students)
c = {
'formsetWithStudents' : formsetWithStudents,
'students' : students,
'survey_count' : survey_count,
'e_students': e_students,
'i_students': i_students,
'survey_formset': survey_formset,
}
c.update(csrf(request))
return render_to_response("reports/screen_many.html", c)
If my URL looks like this: http://127.0.0.1:8000/screen_many/?e_1=13&e_2=12&i_1=14 The view makes 3 survey sets all the while complaining that there is an
UnboundLocalError at /screen_many/
local variable 'ss' referenced before assignment
I feel like I need to make a separate view just for the ajax and I want the SurveySet object to only be created once.
So, in other words. I am filling in forms of a formset which update after clicking "view next form" This is in my template.
$('.next').click(function(){
$(this).parent().hide()
$(this).parent().next().show()
var posting = $.post('/screen_many/', $('form').serializeArray() );
posting.done(function(response){
console.log(response)
});
Or I could send the POST data here:
def save_as_you_go(request):
if request.is_ajax():
# Get the surveyset from POST
ss = request.POST['form-0-surveyset']
surveyset = get_object_or_404(SurveySet, pk=ss)
surveys = surveyset.survey_set.all()
SurveyFormSet = inlineformset_factory(SurveySet, Survey, form=SurveyForm, can_delete=False, extra=0)
survey_formset = SurveyFormSet(request.POST, instance=surveyset)
if survey_formset.is_valid():
for form in survey_formset.forms:
student = form.save(commit=False)
student.surveyset = surveyset
student.save()
return HttpResponse('saved.')
else:
return HttpResponseRedirect('/')
But then I get
[u'ManagementForm data is missing or has been tampered with']
Forgive me if my answer seems naive--I am new to Python and Django, but it looks like you are setting the ss variable in the non-ajax request and then referencing it in the ajax request. Perhaps you can set ss prior to the if statements?
#set ss variable before if statements
ss = SurveySet()
ss.user=request.user
ss.save()
if not request.is_ajax():
###do your non-ajax request stuff
if request.is_ajax():
###do your ajax request stuff

Dyamic Linq .Net 4 error 'userid' could not be resolved in the current scope or contex

I am trying to use Dynamic Linq library in my code, but it gives this error
'UserId' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. Near simple identifier, line 6, column 1
and here is my code
TestDB db = new TestDB();
string filter = "UserId == 15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
Not so familiar with dynamic Linq but from your error message:
'UserId' could not be resolved in the current scope or context. Make
sure that all referenced variables are in scope, that required schemas
are loaded, and that namespaces are referenced correctly. Near simple
identifier, line 6, column 1
Please try this:
1.) Is the column UserId a Integer and not a String? Mabye you need to use:
string filter = "UserId='15'";
2.) Try to pass in the filter parameter as a second argument:
GridView1.DataSource = db.SearchSummaries.Where("UserId = #0", 15);
3.)
I don't know if you are able to run "regular" Linq queries, but if you are, try:
GridView1.DataSource = db.SearchSummaries.Where(search => search.UserId == 15);
GridView1.DataBind();
Try this:
TestDB db = new TestDB();
string filter = "xi => xi.UserId == 15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
Or this:
TestDB db = new TestDB();
string filter = "UserId=15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
EDIT: I realize this isn't dynamic linq...but it should work regardless as long as your data structure is correct. Could you post that?

Django - JSON response with serialized object

I am trying to send a serialized object using JSON. Here is my view code:
if request.is_ajax():
resp = {}
if request.POST:
if form.is_valid():
g = form.save()
resp['graph'] = serializers.serialize('json', [g, ])
resp['success'] = True
else:
resp['errors'] = form.errors
resp['success'] = False
return HttpResponse(simplejson.dumps(resp), mimetype='application/javascript')
return render(request, 'graph/inlines/create.html', {'form':form})
The problem is (rather obviously) that the 'graph' object I am trying to return is being serialized twice (once with serializers.serialize and again when I used simplejson.dumps) and the object is being received as a json string.
I tried just doing this:
resp['graph'] = g
But it throws a server error as the object obviously isn't serialized when I try to use simplejson.dumps.
Is there a way I can tell it to ignore this key when dumping the data? Would appreciate any help.
Rather than serializing the graph queryset to json the first time, use serializers.serialize('python', g) to convert it to a Python dictionary first. Then the whole thing will be converted to json at the end.

Resources