looping from database and no implicit conversion of Symbol into Integer - ruby-on-rails

I encounter a strange problem when trying to alter values from a Hash. I have the following setup:
def index
data, total = Role.with_filtering(params, current_holding_company)
data.each do |total_user|
total_user = { total_user: RoleUser.where(role_id: data[:id]).group(:user_id).count.to_s }
data[:total_user] = total_user
end
respond_to do |format|
format.json { render json: { data: data, total_count: total }.to_json, status: 200 }
end
end
When I execute this code I get: "TypeError: no implicit conversion of Symbol into Integer" . What am I doing wrong?
data is output from database, so my goal is i want to add total_user in every record with add new key and value into data

This might not completely solves your issue but hopefully will guide you to the correct path.
In ruby the error TypeError: no implicit conversion of Symbol into Integer usually happens when you miss treat an array!
lets suppose you have
numbers = [1,2,3]
#now
numbers[0]
# > 1
numbers[2]
# > 3
#But
numbers[:1]
# throws TypeError: no implicit conversion of Symbol into Integer
So, you must be passing a symbol on an array [] operator by mistake
One way to debug this kind of issues is by checking class type of your objects, something like this in the consol
data.class
# > Array (for example)

try this....
def index
data, total = Role.with_filtering(params, current_holding_company)
data.each do |total_user|
total_user = { "total_user" => RoleUser.where(role_id: data[:id]).group(:user_id).count.to_s }
data[:total_user] = total_user
end
respond_to do |format|
format.json { render json: { data: data, total_count: total }.to_json, status: 200 }
end
end

Related

Parse Json Request from CURL in Rails

I need to parse Json data from curl request.Need to split Mac,Parameter,datatype,value from below curl request and pass those data's as input for set method(For each Mac separately).Can anyone please guide how to split?
curl -k -s -H "Content-Type: application/json" -d '{"Data": {"Mac":"10.43.33.34","Parameter":"Device.wifi","datatype":"string","value":"5Ghz"},{"Mac":"15.23.43.48","Parameter":"Device.wifi","datatype":"string","value":"2.4GHZ"}}' http://test:3000/api/executions_api_set/
Set API
def show
client = SetClient.new
versionResponse = client.set_req(mac,parameter,datatype,value)
if versionResponse.code == "200"
value = JSON.parse(versionResponse.body)
render json: {Mac: mac,Response:value}, status: :ok
else
render json: {Mac: mac,Parameter: parameter,status: 'Failed',responsecode:versionResponse.code}, status: :ok
end
end
end
end
end
Updated Code
def create
value = ''
client = SetClient.new
params["Data"].each do |mac_attributes|
#mac_address, #Parameter, #dataType, #value = mac_attributes.values_at("Mac", "Parameter", "datatype", "value")
#versionResponse = client.set_req_api(#mac_address,#Parameter,#dataType,#value)
puts "versionResponse.status_code #{#versionResponse.code}"
end
if #versionResponse.code == "200"
value = JSON.parse(#versionResponse.body)
render json: {Mac_address: #mac_address,Response:value}, status: :ok
else
render json: {Mac_address: #mac_address,Parameter:#Parameter,status: 'Failed',responsecode:#versionResponse.code}, status: :ok
end
end
end
end
I'm not entirely sure what you're trying to do, but if you want the controller to call a method for each JSON object in the array, it would look something like:
def show
params["Data"].each do |hash_of_mac_attributes|
mac, parameter, datatype, value = hash_of_mac_attributes.values_at("Mac", "Parameter", "datatype", "value")
method_you_want_to_call(mac, parameter, datatype, value)
end
This is assuming that rails is correctly detecting and parsing the JSON body into the params hash for you. If it's not, that's a separate issue that can be addressed.
UPDATE
In order to return the result from each call to the external service we need to store each call in an array and render the array in the response. Something like the following:
def show
json_array = params["Data"].map do |hash_of_mac_attributes|
mac, parameter, datatype, value = hash_of_mac_attributes.values_at("Mac", "Parameter", "datatype", "value")
response = client.set_req_api(mac, parameter, datatype, value)
build_json_for_mac_lookup(response: response, mac: mac, parameter: parameter)
end
render json: json_array
end
def build_json_for_mac_lookup(arguments:, mac:, parameter:)
json_body = {Mac_address: mac}
if response.code == "200"
json_body.merge(Response: JSON.parse(response.body))
else
json_body.merge(Parameter: parameter, status: 'Failed', responsecode: response.code)
end
end

Rails how to return single JSON object instead of array of JSON objects?

I am limiting to 1, so I thought it would simple return an object in this case the same as .find_by_email
Code:
# GET /users/:identified/type/:social_type
# Returns a single record - so limit 1
def find
#user = User.where("identified = ? AND social_type = ?", params[:identified], params[:social_type]).limit(1)
if not #user.empty?
render json: #user.as_json, status: :created
else
render json: #user, status: :not_found
end
end
Current Response:
[{"id":7,"voy_num":null,"voy_pin":null}]
How can ensure I return a single JSON object?
To get the single object, use first with where like this:
#user = User.where("identified = ? AND social_type = ?", params[:identified], params[:social_type]).first

Rails Render JSON Object instead of entire array

In my controller I have the present code that results in a JSON array, even though there is only one result:
def getSharedSpecial
#result = Campaign.find_by_sql("SELECT
id
,name
,image
,ad_caption
,ad_details
FROM campaigns
WHERE id = " + params[:shared_campagin_id].to_s + "
LIMIT 1;")
respond_to do |format|
format.html
format.json { render json: { special_shared: #result }}
end
end
returns:
"special_shared":[
{
"id":41,
"name":"tester the way",
"image":{
"url":"/uploads/campaign/image/41/Gilded_pic.jpg"
},
"ad_caption":"yfftitu6",
"ad_details":"jku"
}
]
}
As can be seen given the [], this is a JSON array.
How can I create just an object and not an entire array?
The problem is that find_by_sql always returns an array even though you are only looking for a single record. There is no need to use find_by_sql and you've opened yourself to SQL injection attacks by doing so, so just write the finder the traditional way:
#result = Campaign.select(:id, :name, :image, :ad_caption, :ad_details).find(params[:shared_campagin_id])

Sort! seems to ignore custom attribute

I have this method to place 'The' at the end of a string if it is at the beginning of the string in Novel.class:
def sort_name
display_name = self.name
if display_name.match(/^the/i)
arr = display_name.split(/^the/i)
display_name = "#{arr[1]}, The"
end
display_name
I have this index method in NovelController:
def index
#novels = Novel.all
#novels.to_a.sort! { |a,b| a.sort_name.downcase <=> b.sort_name.downcase }
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #novels }
end
end
In the view I just display the sort_name. The sort_name is being displayed but the novels are still ordered by name. Does anybody see a flaw? Thanks.
The problem here is that sorted array is discarded.
#novels.to_a
This returns a temporary array (which isn't saved anywhere). That temp array is then sorted in-place and forgotten, because you don't have any references to it.
Solution: save it into a variable.
#novels = Novel.all.sort { |a,b| a.sort_name.downcase <=> b.sort_name.downcase }
Also, you have a bug in your sort_name code. It returns values like these:
# for name "The Yellow God"
display_name # => " Yellow God, The"

Geojson data format output properly in a rails app

i m trying to implement a service that displays data in geojson format.
I hit my database with this :
sql =
"select ST_AsGeoJSON(boundaries)
from cluster_shapes
where category = '#{params[:category]}'
and area_id =
(select id
from areas
where name = '#{params[:city]}' )"
connection = ActiveRecord::Base.connection
#clusters = ActiveRecord::Base.connection.execute(sql)
respond_to do |format|
format.json { render json: #clusters }
end
And I get ugly results that is not valid geojson
[
{
st_asgeojson: "{"type":"Polygon","coordinates":[[[23.819537,38.039409],[23.81892,38.04068],...}"
,
st_asgeojson: "{"type":"Polygon","coordinates":[[[23.919537,38.039409],[22.81892,38.04068],...}"
,
...
If I remove the ugly part st_asgeojson and make it look like this , it is valid geojson.
{"type":"Polygon","coordinates":[[[23.819537,38.039409],[23.81892,38.04068],[23.820912,38.040237],[23.8209752169298,38.0400047630785],[23.8209519774174,38.0399755885062],[23.8205266,38.0394558],[23.819537,38.039409]]]}
So the question is how do i get rid of "st_asgeojson" ,or am i doing it wrong ?
PS:A model exist, if query is modified the result is pretty the same.
It seems like what you want is simply nested inside your #clusters json, so you can simply parse it out...
instead of:
format.json { render json: #clusters }
you should change it to
format.json { render json: #clusters[0].st_asgeojson }
Or if you are expecting more than one result to be returned from you sql query, try
format.json { render json: #clusters.map {|x| x.st_asgeojson }}

Resources