Rails How Can I Iterate Over JSON Field - json

I'm trying to play around with DALLĀ·E 2 and what I'm trying to do is simply call their image creation API and display the images using the image URLs they return.
I'm getting stuck on how to show the images on my web page based on the JSON response.
What I've done is save the response in a JSON attribute for my ImageRequest model.
So my code looks like this:
def new
#image_request = ImageRequest.new
end
def create
#image_request = ImageRequest.new(image_request_params)
client = OpenAI::Client.new(access_token: "my_key")
response = client.images.generate(parameters: { prompt: #image_request.prompt, n: #image_request.versions })
#image_request.urls = response
respond_to do |format|
if #image_request.save
format.html { redirect_to image_request_url(#image_request), notice: "Image request was successfully created." }
format.json { render :show, status: :created, location: #image_request }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #image_request.errors, status: :unprocessable_entity }
end
end
end
def show
#image_request = ImageRequest.find(params[:id])
end
But what I'm trying to determine is how can I parse and iterate the JSON and show the images?
# in psuedo code what I'm trying to do:
<% images.each do |i| %>
<%= image_tag "url" %>
<% end %>
This is what the OpenAI response is:
{
"created": 1674850160,
"data": [
{
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/...."
},
{
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/..."
}
]
}
When I look at the stored value in the JSON attribute (after create) in #image_request.urls, it's:
{"created"=>1674850160, "data"=>[{"url"=>"https://oaidalleapiprodscus.blob.core.windows.net..."}, {"url"=>"https://oaidalleapiprodscus.blob.core.windows.net/private/..."}]}
I've looked at these SO questions and experimented, but I can figure out how to just iterate through the data.url(s) returned.
Iterating over JSON in Rails
How do I parse JSON with Ruby on Rails?
Access JSONB fields as normal ActiveRecord attributes
Iterating over JSON in Rails
Loop through API response with .each

If response is {"created"=>1674850160, "data"=>[{"url"=>"https://oaida... then the JSON has already been parsed for you into a Ruby data structure. You then need to turn that into a list of URLs.
Pluck each "url" value from the Hashes in the "data" Array.
#image_request.urls = response["data"].pluck("url")
Now you have an Array of URLs which you can iterate through.
<% image_request.urls.each do |url| %>
<%= image_tag(url) %>
<% end %>

Related

Open JSON File in Rails and Stimulus

I have a select form which determines which values are shown in a table. The values are stored in a json file. My Question is: what is the best way to do this cuz i have a gut feeling smth might be wrong with my solution.
Im able to open the json file and save it in a json/jbuilder object in my controller and then call the object in my view and pass the json in the select which calls a stimulus function, which then handles what is shown on the table.
Main Controller:
class MainController < ApplicationController
def index
#itemsJSON = JSON.parse(File.read('db/data.json'))
end
end
Index View
<%= form_with do |form| %>
<%= form.select :city, [['all'], ['critical'],['error'],['warning'],['info'],['debug']],
{ prompt: "Select Item Type" },
data: { controller: "dropdownTable", value: #itemsJSON,
action: "change >dropdownTable#selectData"} %>
<% end %>
Stimulus Function
Code that doesnt work gives back error: localhost:8080/main/db/database.json not found which // i dont understand why
//fetch('/db/data.json')
// .then((response) => response.json())
// .then((json) => console.log(json));
export default class extends Controller {
selectData(event){
... code that works
}
}

How to render a custom action results from controller in views using Rails 7 without refreshing the page?

I have this a custom action in Task controller, which has if else
statements and returns Api calls from Safe browsing api, which I need to render to users
in index.html.erb without refreshing the page. I've tried Ajax but it doesn't seem to
work correctly.In addition, I've tried to search and follow some Hotwire and Turbo
tutorials but they seem to solve complicated problems unlike my problem.
My problem and solution are simple, a user submits link to the server to be checked by
Google Safe Browsing API and return results back to the user rendered in the same
page without refreshing. I currently have them rendered in a different page by using
for example
render plain: "" and return
Finally, this's my code and I need a simple solution to render the custom action results
to users without refreshing the page.
This's check_url action in tasks_controller.rb
def check_url
#id = params[:id]
#result = params[:result]
if params[:link].present?
api_key = ENV[""]
# Set up the request parameters
url = params[:link]
formatted_url = canonicalize_url(url)
threat_types = ["MALWARE", "THREAT_TYPE_UNSPECIFIED", "SOCIAL_ENGINEERING", "UNWANTED_SOFTWARE", "POTENTIALLY_HARMFUL_APPLICATION"]
platform_types = ["ANY_PLATFORM"]
body = {
client: {
clientId: api_key,
clientVersion: "1.0.0",
},
threatInfo: {
threatTypes: threat_types,
platformTypes: platform_types,
threatEntryTypes: %w[URL THREAT_ENTRY_TYPE_UNSPECIFIED EXECUTABLE],
threatEntries: [
{ url: formatted_url },
],
},
}
# Set up the request headers
headers = {
"Content-Type" => "application/json",
}
# Make the request to the Safe Browsing API
response = HTTP.post(
"https://safebrowsing.googleapis.com/v4/threatMatches:find?key=",
json: body,
headers: headers,
)
# Check the response
if response.code == 200
data = JSON.parse(response.body)
puts JSON.pretty_generate(data)
#result = response.body
if data["matches"].try(:empty?)
render plain: "The URL is safe" and return
else
render plain: "The URL is not safe" and return
end
else
render plain: "An error occurred"
end
else
puts "link variable is empty"
end
puts "Response code: #{response.code}"
puts "Response body: #{response.body}"
puts "Request parameters: #{body}"
puts "Request headers: #{headers}"
end
private
def task_params
params.require(:task).permit(:link, :result)
end
end
This's the submission form in _form.html.erb
<%= form_tag("/check_url", method: "post") do %>
<%= label_tag(:link, "Enter a link:") %>
<%= text_field_tag(:link) %>
<%= submit_tag("Submit") %>
<% end %>
This's index.html.erb
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice">
<%= notice %>
</p>
<% end %>
<h1 class="font-bold text-2xl">Task Manager</h1>
<div class="mt-4">
<%= render "form", task: #task %>
<%= render 'tasks/check_url' %>
</div>
Thank you all and please ask any questions or requests, I'm new to Ruby on
Rails and want to grasp it.

Ruby On Rails | What is format.html/json for?

So I have been going through Rails Zombies and have gotten to the part explaining format.html and .json
My question is what do these lines of code do, and why do we have them? If I write these methods or actions without these format codes they work perfectly fine, as i'd assume they simply display in html format by default? If somebody could clear up exactly what this code does I'd be grateful, I also do not fully understand what JSON is.
def create
#zombie = Zombie.new(zombie_params)
respond_to do |format|
if #zombie.save
format.html { redirect_to #zombie, notice: 'Zombie was successfully created.' }
format.json { render :show, status: :created, location: #zombie }
else
format.html { render :new }
format.json { render json: #zombie.errors, status: :unprocessable_entity }
end
end
In simple terms:
If the request wants an HTML page, it will perform the instructions set by the block given to format.html.
If the request wants application/json (like when you make an Ajax request), the response will be given as instructed in the block given to format.json.
You should know what JSON means before delving into creating any web service. See http://www.json.org/

Send an http response to another site

Noob
How should I send a single string variable to another site from my rails app? ie the outside service sends a get request to my controller/route and then the controller must respond with the string (and I assume a response code). The string is intended to be added to their html code.
In my controller should I
render :text => "string"
or
respond_with("string) #as xml or json
or something completely different?
Just try the following code. Here your application gives the text and json as per the request.
respond_to do |format|
format.json do
render :json => 'string'
end
format.html do
render :text => 'string'
end
end

Show data after AJAX call, how to render in controller?

I would like to use link_to to call a controller action named show. This happens, I get a 200 message. Now I want to update a div with the content that is being returned.
Code in controller:
respond_to do |format|
format.html # show.html.erb
format.js
end
Code in view, link and JavaScript:
<%= link_to "Show analysis", company_comparison_path(3), :remote => true , :id => "thelink" %>
<div id="replaced"> will be replaced </div>
<script>
$('#thelink').bind('ajax:complete', function() {
$('#replaced').html(data)
});
</script>
I think I still don't understand how to return the HTML or JavaScript from the controller properly into the JavaScript. If I replace the word "data" in the JavaScript with some text in brackets, I get proper output. But how do I get the result from the controller action?
You were almost there, but you need to tell the bound function what the actual html content is you want to insert into your #results div. When you call .html() on $('#replaced') the variable you use (data) is still undefined.
Try the following:
$('#thelink').bind('ajax:complete', function(event, data) {
$('#replaced').html(data.responseText);
});
edit: Oh, something to keep in mind is that this may render your view including the layout which is probably not what you want. You can add something like render layout: false if request.xhr? to your controller to prevent the layout from showing up on ajax requests.
If you want to return richer content from the AJAX response, you can render the view from the controller by the :render_to_string method.
See more: http://apidock.com/rails/ActionController/Base/render_to_string
respond_to do |format|
format.html # show.html.erb
format.js {
#content = render_to_string(:partial => 'some_partial_view')
}
end