Home > Enterprise >  Rails - Partial View form to execute SQL stored procedure
Rails - Partial View form to execute SQL stored procedure

Time:08-15

I've got a partial view:

<%= form_with url: admin_command_path() do |f| %>
    [form stuff]
<%= f.submit :onclick(?) button_to? link_to? %>
<% end %>

This view/form doesn't need to create/update the model referenced, but should instead ONLY execute a sql() that I currently have stashed in ApplicationHelper AND in the referenced ^Command module, just to see where I can call it from. Little bit of pasta, meet wall situation :/

def command_string(id)
  execute = ActiveRecord::Base.connection.exec_query("
  exec [dbo].[FunctionName] #{id}")
end

I've tried just about all manner of form action, url routing, etc no no avail.

The ideal outcome is just calling the dang sql function from the form's submit button, or in a in the view itself, but either the function executes on load (rather than on click) or doesn't execute at all.

Yall don't get too hung up on the missing params, code for rough context. Just looking for an onclick -> sql exec path forward. Thx

CodePudding user response:

You're thinking about this completely wrong.

Helpers are mixins/junk drawers where you can place code that you intend to resuse in your controllers and views. They are not called directly from your routes and "I want method X in my helper to be called when a button is clicked" isn't a very good way of going about it.

If you want to something to happen server side when the user clicks a link/form/button etc its done by sending a HTTP request from the client to the server. This can be a syncronous (normal) or asyncronous (AJAX) request.

You make Rails respond to HTTP requests by creating a route which matches the request and a controller action which sends a response.

# routes.rb
post 'admin_command', as: :admin_command,
                      to: "admin#do_the_thing"
class AdminController < ApplicationController
  def do_the_thing
    # This code is vulnerable to a SQL injection attack if the 
    # id originates from user! Use a parameterized query!
    result = ActiveRecord::Base.connection.exec_query("
  exec [dbo].[FunctionName] #{id}")
    render text: "Okelidokeli duderino"
  end
end
<%= form_with url: admin_command_path, local: true do |f| %>
  <%= f.submit %>
<% end %>

You follow the same basic structure in Rails applications even when there is no model or view involved. Don't think in terms of functions - think in terms of the API your Rails application provides to the client and how you're going to respond.

Its only later if you need to resuse the code which performs the SQL query across controllers or in your view that you would place it in a helper when refactoring - it has no merit in itself.

If you then want to make this asyncronous (so that the page doesn't reload) you can do so by using Rails UJS or Turbo depending on your rails version. Or you can do from scratch by attaching an event handler to the form and sending an ajax request with the Fetch API.

But you should probally figure out the basics of the syncronous request / response cycle first.

  • Related