Seed Rails SQLite Database from a JSON file - ruby-on-rails

I'm new to Rails (using 5.0.2). I want to seed my empty SQLite db from a JSON file.
I scaffolded my Product resource, in seed.rb added:
records = JSON.parse(File.read('/home/projects/test1/public/products.json'))
records.each do |record|
ModelName.create!(record)
end
Then launched rake db:seed.
I got an error:
rake aborted!
JSON::ParserError: 409: unexpected token at '{
My JSON consists of products with various properties:
[
{
"model": "Brand",
"brand": "Brand",
"price": 19.99,
"currency": "GBP",
"link1": "https://www.amazon.co.uk/Call-Duty-Ghosts-Hardened-Xbox/dp/B00ECQJ0BS/ref=pd_sim_107_4?_encoding=UTF8&psc=1&refRID=9GE6A8BW61S1FG4H3ZRJ",
"link2": "",
"size1": "{min: "5",max: "90"}",
"net_weight": "263 kg",
"size2": "{w: "19.4",h: "11.7",z: "12.7"}",
"d1": "",
"color": "['Black','White']",
"materials": "plastic+concrete, glass ceiling",
"models": "['model 1', 'model 2', 'model 3', 'model 100']",
"props": "['prop1', 'Prop1', 'Prop1']",
"": "",
"size3": "{w: "100",h: "200",z: "500"}"
},
]
How can I fix this JSON file and correctly seed my db with the products data from it?
Is it the best way to import manually created JSON files into Rails, or it's better to try some other approach?

The problem is with the size1, size2, and size3 properties. For each of those keys, the value contains a double-quote. If you convert those to single quotes or escape them by putting a \ before them, your JSON should parse correctly.

Related

Upload a file from ActiveStorage to an API

I'm trying to upload a file to an API with Httparty gem.
Here is the requested format, from the documentation of this API:
Method: POST
Content-Type: application/json
{
"name": "filename.png",
"type": 2,
"buffer": "iVBOR..."
}
My document is stored with ActiveStorage, here is my function to download it and generate the parameters HASH:
def document_params
{
"name": #document.file.filename.to_s,
"type": IDENTIFIERS[#document.document_type],
"buffer": #document.file.download
}
end
Then I send the data with this function:
HTTParty.post(
url,
headers: request_headers,
body: document_params.to_json
)
The problem is that when I do document_params.to_json, I get this error:
UndefinedConversionError ("\xC4" from ASCII-8BIT to UTF-8)
If I don't call to_json, data is not sent as a valid json, but as a hash representation like this: {:key=>"value"}
I would like to just send the file data as binary data, without trying to convert it to UTF-8.
I found a solution: encoding the file content to Base64:
def document_params
{
"name": #document.file.filename.to_s,
"type": IDENTIFIERS[#document.document_type],
"buffer": Base64.encode64(#document.file.download)
}
end

How to refer one avro schema inside another one

I need to refer to this Student schema from inside another schema:
{
"type": "record",
"namespace": "data.add",
"name": "Student",
"fields": [
{
"name": "Name",
"type": "string"
},
{
"name": "Age",
"type": "int"
}
]
}
This is the parent Address schema which needs to refer to Student:
{
"type": "record",
"namespace": "data.add",
"name": "Address",
"fields": [
{
"name": "student",
"type": "Student"
}
]
}
The above throws an error when I build using Gradle with the Avro plugin. Both schemas are located in the same folder.
Sorry if I'm too late to the party, but it looks to me like both the maven avro plugin and the avro-tools compiler do not determine dependency order when loading, but will succeed if you order them yourself on the commandline. I have an example demonstrating this from your sample files in a standard maven directory structure.
When I put the schema with no dependencies first in the commandline, it succeeds:
java -jar /path/to/avro-tools-1.11.0.jar \
compile schema \
src/main/avro/student.avsc \
src/main/avro/address.avsc \
target/generated-sources/avro
ls target/generated-sources/avro/data/add/*
target/generated-sources/avro/data/add/Address.java target/generated-sources/avro/data/add/Student.java
When I put the schema with dependencies first in the commandline, it fails:
java -jar /path/to/avro-tools-1.11.0.jar \
compile schema \
src/main/avro/address.avsc \
src/main/avro/student.avsc \
target/generated-sources/avro
Exception in thread "main" org.apache.avro.SchemaParseException: "data.add.Student" is not a defined name. The type of the "student" field must be a defined name or a {"type": ...} expression.
at org.apache.avro.Schema.parse(Schema.java:1676)
at org.apache.avro.Schema$Parser.parse(Schema.java:1433)
at org.apache.avro.Schema$Parser.parse(Schema.java:1396)
at org.apache.avro.tool.SpecificCompilerTool.run(SpecificCompilerTool.java:154)
at org.apache.avro.tool.Main.run(Main.java:67)
at org.apache.avro.tool.Main.main(Main.java:56)
This was successful:
{
"type" : "record",
"namespace" : "data.add",
"name" : "Address",
"fields" : [
{
"name": "student",
"type": "data.add.Student"
}
]
}

How to handle array response from elastic api with faraday?

I want to receive all Elastic Cloud configuration templates from the Elastic Cloud API with faraday in my Ruby on Rails application.
I've tried to workaround and modify the api call, but it's not possible to not get an array as a response.
This is the repsonse from the api:
[
{
"name": "Small Template",
"id": 1
},
{
"name": "Medium Template",
"id": 2
},
{
"name": "Big Template",
"id": 3
}
]
This is my faraday configuration.
Faraday.new(url: "https://#{ENV['ECE_USERNAME']}:#{ENV['ECE_PASSWORD']}##{ENV['ECE_HOST']}") do |c|
c.response :json, parser_options: {symbolize_names: true}
c.response :logger
c.use JSONParser
c.adapter Faraday.default_adapter
end
And the api call:
#conn.get('/api/v1/platform/configuration/templates/deployments?stack_version').body
This is the error message I receive
undefined method `has_key?' for #<Array:xxxxx>
I don't want to use anything else, but faraday. I'm open to new gems to help faraday, but this client should stay.
How can I setup faraday to handle the array response or how can I workaround my problem?

JSON response_body generated by rspec_api_documentation gem is empty (Rails)

I've successfully used rspec_api_documentation gem to generate docs for some other resources in an application.
But when I do the same for a new resource, the JSON file's response_body is empty (though the rest of the JSON exists). And I'm unsure why this is happening.
response_body in generated JSON:
"response_body": "{\n \"data\": {\n \"notes\": [\n\n ]\n },\n \"status\": 200,\n \"message\": \"Ok\"\n}"
Outputed API docs:
{
"data": {
"notes": [
]
},
"status": 200,
"message": "Ok"
}
What I've done:
Tested the endpoint with a curl and can confirm it returns a full response (now I'm just trying to build the documentation)
Created note_factory.rb
Added #notes = create_list(:note, 1,...) in a before(:all) do block at beginning of notes_spec.rb (and printed to console to confirm it creates an object)
Also created below as the test.
get '/api/v1/notes' do
example 'Return all notes' do
explanation 'Return all notes within an account.'
set_jwt_auth_headers(#api_reader)
do_request
expect(status).to eq 200
end
end
I'm confused what I might be missing that causes the JSON response related to RAD to be empty.
Does anyone have any ideas what might cause this?

JSON::ParserError: 757: unexpected token at '{ Rails

I don't understand. Is it the double quotes? I'm trying to import from a json file into my database.
JSON::ParserError: 757: unexpected token at '{
"id": 4,
"name": "Backcountry Skiing",
"keywords_list": null,
"keywords": [
Here is my rake task:
require 'json'
namespace :fieldfacts do
desc "Import Topics"
task :import_topics => :environment do
records = JSON.parse(File.read('public/topics.json').gsub('\"', '"'))
records.each do |record|
a = Topic.new
a.name = record['name']
a.save
end
end
end
You can covert this string to hash using eval like this:
eval(hash_string)
What you have is JSON string that's why it was raising error.
Note: Just be careful using eval because it can inject malicious code inside your system depending upon where your hash come from.

Resources