Open JSON File in Rails and Stimulus - json

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
}
}

Related

Rails How Can I Iterate Over JSON Field

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 %>

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.

Rails controller rendering HTML as plain text, instead of a form

On my site I want a form to be rendered based on what type of data the user is inputing. When I call the controller method in my view, it's outputting tons of HTML where the form should be as plain text starting from DOCTYPE to . I'm using a post form that was previous in place statically to try it out.
Controller:
def feed_form(form_type)
form_type = %w{type_1 type_2}.include?(form_type) ? form_type : 'post'
render "_#{form_type}_form"
end
And the view calling the action:
= feed_form 'post'
And the form:
.feed-form
%h3 News Feed
= form_for(#post) do |f|
= render 'shared/error_messages', object: f.object
.field
= f.text_area :content, placeholder: "Make your new post here..."
= f.submit "Post", class: "post-button"
You are don't supposed to call controller methods from a view.
You must prepare all the data for view rendering (e.g. all required models) in controller method, and put it into #variables.
And then in view you write all your html using already prepared #variables, you can call helpers methods from a view, but not controller's.
Try to put your def feed_form(form_type) code into a helper.
P.S.: and read something about MVC architecture.

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

Passing parameter in a Ruby function from HTML

I have two files. .rb (with Ruby code) and .erb(HTML file with some ruby script). I am calling a Ruby function in .rb from .erb.
.erb
Click here
.rb
def showProducts(param)
//Some code
end
I am able to call a function without passing parameters to it. But as and when I pass parameters to function and then call it, I receive an error. I know this is the incorrect way to call a parametrized function from .erb. What is the correct way of calling a parameterized function from HTML?
If you add in another key/value pair to the hash in url_for
<%= url_for :action => :showProducts, :product => "toaster" %>
Your URL should go from, say, http://localhost:3000/showProducts to http://localhost:3000/showProducts?product=toaster
Here, we're adding parameters to the GET request. To access these parameters in the controller we use the params hash. For example to get the product (toaster):
params[:product] #=> "toaster"
I found the solution to my problem :
<a href="<%= url_for :action => :showProducts, :id=> 'Hello' %>">
.rb function:
def showProducts(param)
//Some code
end
I found the solution
def showProducts
#params['product']
end