ajax post to external database from Rails app - ruby-on-rails

I am trying to insert data from a form built with Ruby on Rails to my SQL Server database. I have connected my database correctly and can pull data from it. I am now trying to post back to it. I am needing help with figuring out how to get the data from the form into the correct columns in my table in the database.
My ajax:
<script>
$('#Favorites').on('submit',function(event){
    var $form = $(this),
    data = $form.serialize();
    var url = 'http://localhost:3000/welcome/insert';
    $.ajax({
        type: 'POST',
        url: url,
        data: data,
        success: function(){
            
alert('Your form has been successfully submitted!');
document.getElementById('Favorites').reset();
window.location.reload();
        },
        fail:function(){
            alert('something went wrong...try again');
        }
    });
return false;
});
</script>
My controller function:
def insert
#ipinsert=Ipdw.connection.execute("insert into [DB_Test02].[dbo].[My_Table] (Report_Name,Report_Link)
values ('I am cool','www.google.com')")
end
Currently I just have a dummy insert statement here to make sure that I can insert into the tables and I can. I just need to know how to break out the form values sent to the controller and how to tell Rails what table and columns to put those values into.

Rails will format the data for you. In controller like this:
{'Report_Name': 'some name', 'Report_link': 'www.example.com'}
and will be accessible via the params.
Your job is now to format the data correctly for the manual execution of the SQL query.
insert_values = "('%s', '%s')" % params['Report_Name'], params['Report_link']
#ipinsert=Ipdw.connection.execute("insert into [DB_Test02].[dbo].[My_Table] (Report_Name,Report_Link) values #{insert_values}")

For the problem of which table to add to your DB server you could specify this in hidden fields in your form and every fieled should have a name, When you say $form.serialize(); it turns it to something like FirstName=Amr&SecondName=Adel and so on where FirstName is the name of the field and Amr is the value of the field, Then you put this serialization into a form of JSON format like {"data": $form.serialize()} and add dataType: "JSON" to your post request, In your Insert function you can get it through params[:data] and split it with& to be something like ['FirstName=Amr','SecondName=Adel'] and every element split it with = so you can get something like this [['FirstName','Amr'], ['SecondName','Adel']].
Hope this helps.

Related

Rails Frontend Trying to save autogenerated data to database without form

I'm new to ruby on rails. I'm trying to save data that is generated by itself to the database. i have looked into and found I was meant to use ajax, however all the videos/forums i have seen are example of ajax that use form and not refreshing page. i want to save data automatically without pressing submit.
Assume that the project is fresh project with postgresql as the database. I have created a database that can hold geo points by using postgis. i have created another page where it has map implemented where i can manully pin location. I want to save the manuuly pinned location to the database.
function onMapClick(e) {
alert("You clicked the map at " + e.latlng);
}
mymap.on('click', onMapClick);
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
The e.latlng holds the geopoint, but i dont know how to save it the database if the user clicks anywhere on the map.
You don't need submit form to use ajax.
Basically what you want is add event listener to the map, and when user click then send ajax request to the controller.
For example, let's say that your map is inside div with id my-map.
If you use jQuery you can write something like this:
$('#my-map').on('click', function() {
# add your logic here
$.ajax({
url: 'your-url',
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
'let': data you want to send to backend
})
}
Hope it works!
EDIT:
After I looked your code I found that you can not have jQuery in your project so you can not use jQuery ajax. You need use vanilla javascript. So instead this snippet above, you can write this.
var xhttp = new XMLHttpRequest();
const params = { saving_location: { geoPoints: e.latlng } }
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == 4 && xhttp.status == 200) {
alert(http.responseText);
}
}
xhttp.open("POST", "/saving_locations", true);
xhttp.setRequestHeader('Content-Type', 'application/json', 'Accept', 'application/json');
xhttp.send(JSON.stringify(params));
Also add protect_from_forgery with: :null_session in your application controller and skip_before_action :verify_authenticity_token in your Saving Location controller.(under before_action).
Here is good blog post why you need this https://blog.nvisium.com/understanding-protectfromforgery
Please notice that you wan't save your database, because your geoPoints type in database is type of point and you send string to rails controller. I never work with points in rails so I can not help you here.(You can always add two columns in db, one for longitude and one for latitude and then store numbers instead point)

Axios Filter table returns counts but not data

I am currently working on ASP.Net MVC project. I am using Vuejs- Axios to get out data from entity data models. So...axios.get (gets the API) and now I am displaying my chart based on the value received.I am also on the same page showing table of data(same api results). The table has a search box, as user enter details to search a particular product my chart should show respective data. The problem is : I am in my javascript for table data: created api request , computed and used method(for filtering data). Now in the same filter method...when I do console.log(response.length)...I get correct filtered records....but when I write response.data….I get msg as undefined...
Kindly let a beginner like me know...how I can use this filtered data to create new chart...
If the filtered data can show correct length...it should be able to show data as well..
Thanks.
Edited: code here...
Javascript for chart( Vue-Chartjs):
var app = new Vue({
el:"#abc"
data:{
chart:null,
loading:false
},
created function(){
this.loading = true
axios.get('api/Work')
.then (function(response){
console.log(response.data)
calculated fields required.....
var ctx= document.getElementById("chart1")
chart....labels, datasets..etc....
Javascript - Loading table)
var app = new Vue({
el:"#abcd",
data(){
return:
fields:[
]},
created function(){
axios.get('api/Work')
.then (function(response){
console.log(response.data)
},
computed:{
mounted(){
this.totalrows= this.totalrows.length
}
},
methods:{
onfiltered(filteritems){
console.log(filteritems.length) =====returns correct table search - i.e filtered table length.....
console.log(filteritems.data)
=====returns undefined...........Stuck up here......
Once I get the filtered data , I can make the new chart based on the filtered values. So this is the place where I need clarifications.
Thanks.

Dynamic dropdown (select_tag) with Ruby on Rails

I've been trying to create 3 dynamic dropdown, wich the first change the content of the sencond and the second change the content of the thrid.
I haven't found an example for doing that, I found an example in which you send all the information to the client and there it is filtered, but it is not what I want.
I want it to interact with the server every time the select has a change.
If somebody has a tutorial or could give a brief example, I would really appreciate that
Thanks
You need 3 things for it to work:
1- Javascript on change event on your select:
// This will monitor your select control and start the process after its content has changed
$('select#my_select_control').change( select_has_changed(this) );
2- Javascript Ajax controller function:
// This will send the selected value to your Rails server
function select_has_changed(obj)
{
// We get the selected value
var value = $(obj).val();
// It's a good idea here to verify the value.
// For example if the value is empty we can empty the content
// of the target select control and do not go through ajax
// We make the ajax call to the rails controller
$.ajax({url: '/path/to/controller/action',
data: {value: value},
// We are requesting for json response, but you can use html if you like
dataType: "json",
// Get method, or other is you like, you just have to
// define it accordingly in your routes
method: 'get'
// This is the function to call when ajax succeed
success: function (data) { fill_up_form(data, obj) }
});
}
// This is called when Ajax was successful , and it will
// fill up your target select control
function fill_up_form(data, obj)
{
content = ... // Here you loop through your json data to create
// a set of OPTION tags
// Or if you used html as dataType, the rails server had it done
// so you can inject directly in your select target control
$('select#my_target_control').html(content);
}
3- Rails controller method
# The action method that receive the ajax call
# you must have set-up your routes accordingly
def get_my_ajax_data
# This fetches the data from the database
# Note that we are using `params` with the same index as
# we used in the `data` hash of the ajax call
# which, in my example is `value`
records = Model.where(field: params[:value])
# For a json request we return a collection of [id, text]
# that can be used to populate your target select control
# As an alternative we could have render a template if
# we was requesting for html content
render json: records.collect{ |r| {id: r.id, text: r.name} }
end

Refresh the Grid with the latest Data in DATABASE

I am using a grid where I am passing the values to the controller class and saving the data to Database, but if I refresh the page the new changes are gone. The datas that were present before saving the grid will be displayed again.
Here is my Code Snippet of ajax call.
$("#btnSaveJobCode").click(function(){
var rowscount = $("#activityCodeRatioDistribution").jqxGrid('getdatainformation').rowscount;
var postdata = "";
var rows = $('#activityCodeRatioDistribution').jqxGrid('getrows');
$.ajax({
url : "saveActivityCodeRatio.htm",
cache : false,
type : "POST",
contentType : "application/json",
async : false,
dataType : "json",
data : JSON.stringify(rows)
}).done(function(data) {
alert("Save Successful.");
$('#activityCodeRatioDistribution').trigger( 'reloadGrid' );
}).fail(function() {alert("fail");});
});
What should I do to get the latest data from Database at each refresh? I am using Spring MVC and JQX grid. Thanks in advance.
to reload grid use below code after ajax call
$("#activityCodeRatioDistribution").jqxGrid('updatebounddata', 'cells');
If your jqxGrid source attribute is retrieving values from DB then above mentioned reload will update the latest values from DB.
The ajax call mentioned above are pretty well. I don't think it has any problem.
Are the data being saved in the database? First of all check that manually.
If no, then correct the code in the controller to save data.
If yes, then, you have to check the source of the jqxgrid which you haven't mentioned here.
In source, check the 'id' that you have mentioned. jqxgrid doesn't display rows if two rows have same 'id'.
So, it would be better if you had given the snippet of jqxgrid too.
Thanks

form serialize problem

I have a form. I am trying to validate it through AJAX GET requests.
So i am trying to send the field values in the GET request data.
$('#uxMyForm').serialize();
the problem it is returning something undecipherable. I have used serialize before. This is totally bizzare.
the return value of serialize is
actionsign_upcontrollersitedataauthenticity_token=oRKIDOlPRqfnRehedcRRD7WXt6%2FQ0zLeQqwIahJZJfE%3D&customer%5BuxName%5D=&customer%5BuxEmail%5D=&customer%5BuxResidentialPhone%5D=&customer%5BuxMobilePhone%5D=&customer%5BuxDateOfBirth%5D=&customer%5BuxAddress%5D=&customer%5BuxResidentialStatus%5D=
i have no idea how to use this.
Thanks
update:
My question is how do i process such a request? like this?
puts params[:data][:customer][:uxName]
my GET request trigger looks like this
$.get('/site/sign_up',{data : $('#uxMyForm').serialize() }, function(data){
alert(data);
});
The above jquery lines generate the request.. on the action method i do the following
render :text => params
when i observe what is sent in the GET,in firebug PARAMS
**data** authenticity_token=oRKIDOlPRqfnRehedcRRD7WXt6%2FQ0zLeQqwIahJZJfE%3D&direct_customer%5BuxName%5D=&direct_customer%5BuxEmail%5D=&direct_customer%5BuxResidentialPhone%5D=&direct_customer%5BuxMobilePhone%5D=&direct_customer%5BuxDateOfBirth%5D=&direct_customer%5BuxAddress%5D=&direct_customer%5BuxResidentialStatus%5D=
the return value that i print in alert has
actionsign_upcontrollersitedataauthenticity_token=oRKIDOlPRqfnRehedcRRD7WXt6%2FQ0zLeQqwIahJZJfE%3D&direct_customer%5BuxName%5D=&direct_customer%5BuxEmail%5D=&direct_customer%5BuxResidentialPhone%5D=&direct_customer%5BuxMobilePhone%5D=&direct_customer%5BuxDateOfBirth%5D=&direct_customer%5BuxAddress%5D=&direct_customer%5BuxResidentialStatus%5D=
How does the form itself look. I have no experience with Ruby on rails - and if it builds the form in a new exciting way - but it looks as if there's only two form elements: authenticity_token and customer - where customer is an array of items. This is the data you posted, but I urldecoded it and put in some linebreaks:
authenticity_token=oRKIDOlPRqfnRehedcRRD7WXt6/Q0zLeQqwIahJZJfE=
&customer[uxName]=
&customer[uxEmail]=
&customer[uxResidentialPhone]=
&customer[uxMobilePhone]=
&customer[uxDateOfBirth]=
&customer[uxAddress]=
&customer[uxResidentialStatus]=
What you could do is to serialize the form to an array and clean it up before sending it using jQuery ajax request. I did something similar once when I had to serialize .net runat-server form elements:
var serializedData = $(form).serializeArray();
for( i=0; i < serializedData.length; i++)
{
// For each item in the array I get the input-field name after the last $ character
var name = serializedData[i].name;
var value = serializedData[i].value;
if( name.indexOf('$') != -1)
name = name.substr( name.lastIndexOf('$')+1 );
serializedData[i].name = name;
}
var ajaxPostData = $.param(serializedData);
So instad of blabla$ABCPlaceHolder$tbxEmail I got tbxEmail in the array. You could do the same to get uxName, uxEmail etc instead of the customer array.
Note then again, however, due to my inexperience with ruby that this may not be the best solution - maybe there's a setting you can change to build the HTML form differently?
Updated:
I'm not sure how ruby works, but after a googling I found you should be able to receive your values using params:customer as an array.
params:customer should contain an array of the values
{:uxName => "", :uxEmail => "" }
I hope that tells you something on how to receive the data. Maybe (warning - wild guess!) like this?
params[:customer][:uxName]

Resources