use JSON object with rails scoped - javascript

I want to the following thing to happen:
When I select a selectbox I want it to send a JSON object through AJAX to my controller like so :
var encoded = $.param(data);
jQuery.ajax ({
url: '/trips',
type: 'GET',
data: {'toSearch' : encoded},
success: function (response) {
//succes
console.log(encoded);
}
});
and use these as params for my query like so
respond_to :json, :html
def index
#trips = Trip.scoped
#trips.where("category_id = ?", params[:category_ids]) if params[:category_ids] # category_ids = array; select * from trips where category_id IN [1,3,4]
respond_with #trips
end
How do I do this? and what is the best way to serialize my JSON object?

You can do the following:
def index
#trips = Trip.scoped
#trips.where("category_id = ?", params[:category_ids]) if params[:category_ids] # category_ids = array; select * from trips where category_id IN [1,3,4]
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #trips }
format.json { render :json => #trips }
end
end
Then you should do whatever you want to in the javascript callback.
Edit
If you want just the json format you can do the following:
render :json => #trips
You can also check the Layouts and Rendering in Rails guide.

Related

Load form object on fetching from ajax

I have a form that renders partial 'form'.
= form_for(#booking, :as => :booking, :url => admin_bookings_path, :html => { :multipart => true }) do |f|
= render partial: "form", locals: { f: f }
Inside the partial form again another partial is rendered based on new_record?.
- if f.object.new_record?
#extra-products
= render partial: 'new_booking_extra_product', locals: { f: f }
- else
= render partial: 'extra_product', locals: { f: f }
In bookings#new, when the user selects particular car_id, I want to show associated products with it through ajax. For that I have used ajax to make a request to bookings#fetch_extra_product.
# Ajax request to fetch product
$('#booking_car_id').on('change', function(e){
var selectedCarId = $("#booking_car_id option:selected").val();
var url = "/admin/bookings/" + selectedCarId + "/fetch_extra_product";
$.ajax(url,{
type: 'GET',
success: function(msg){
},
error: function(msg) {
console.log("Error!!!");
}
});
});
# Bookings#fetch_extra_product
def fetch_extra_product
#car_id = params[:car_id] || Car.all.order('id desc').first.id
#extra_product = Car.find(#car_id).extra_products
respond_to do |format|
format.js
end
end
The fetch_extra_product.js.erb looks as follow:
$('#extra-products').html('$("<%= j render(:partial => 'new_booking_extra_product', :locals => {:f => f}) %>")');
But the form object (f) is undefined on this state. What's the best way to fetch the object or the best way to get through this problem?
You'll want to render a partial view with the associated products server-side when the Ajax request is received. Then you can send the HTML from that partial as part of your response and use the Ajax success callback to attach the partial view to the DOM however you want it. Then you can have (in your controller) code something like this:
def fetch_extra_product
# Unless you're using #car_id in a view or something, I'd just
# just use a local variable instead of an instance variable
#
car_id = params[:car_id] || Car.all.order('id desc').first.id
#extra_products = Car.find(car_id).extra_products
respond_to do |format|
format.js { render partial: 'extra_products_div', status: :ok }
end
Then your partial code is something like this:
<div class="extra-products">
<% #extra_products.each do |product| %>
<h2><%= product.name %></h2>
...
<% end %>
</div>
That way, your JavaScript can then go along the lines of:
$.ajax(url, {
type: 'GET',
success: function(msg) {
$('#foo').attach(msg);
},
error: function(msg) {
console.log('Error!!!');
}
});
One other comment: If your API is only going to get a request to this route via Ajax, you don't need the respond_to block. In that case you can just put the render partial: 'extra_products_div', status: :ok under the line where you
define #extra_products.

rails 500 internal server error

i'm trying to fetch data from database in rails, this is my controller file
class PathsController < ApplicationController
before_filter :authenticate_user!
skip_before_filter :verify_authenticity_token
def getall
#result = Path.select('x', 'y')
end
respond_to do |format|
format.json { render json: #result }
end
end
Here is my js function
function makelines()
{
$.ajax({
type: "GET",// => method type
url: "/path", // => Target function that will be return result
contentType:"application/json",
success: function(result){
result = JSON.parse(result);
console.log(result);
}
});
}
Here is the route
match '/path => 'Paths#getall', via: [:get, :post], :default => { :format => 'json' }
The first thing you should do in this circumstance is consult your console or logs; that will be the most helpful in pinpointing the exception.
That said, I'll take a guess and warrant that the issue is that you are invoking a respond_to outside of a controller action
def getall
#result = Path.select('x', 'y')
end
respond_to do |format|
format.json { render json: #result }
end
Should be:
def getall
#result = Path.select('x', 'y')
respond_to do |format|
format.json { render json: #result }
end
end
Let's improve your code a little bit:
def getall
#results = Path.select('x', 'y')
respond_to do |format|
if #results.count > 0
format.json { render json: #results, , status: :ok }
else
format.json { render json: #results.errors, , status: :not_found }
end
end
end
Per Rails conventions it would be better to return results instead of result as you are returning more than 1 item.
I also think that as you are returning a JSON object to your AJAX method it would be good to return either a 200 (:ok) or a 404 (:not_found, in the event no record is in the database)

json data not being passed in Rails

I am trying to make a very simple ajax call with Rails 4, but the json response is not being retrieved properly.
Here's the script:
$(document).on "submit", "form[name=upvote-form]", ->
form = $(this)
$.post "/vote", $(this).serialize(), (data) ->
if data["status"] is true
form.find("input").addClass "disabled"
$("#vote-count-".concat(form.find("#question_id").attr("value"))).html data["votes"]
else
return
return
alert(data['votes']) is undefined, which made me try to find what was going wrong.
Then in the console I could see this:
ArgumentError (Nil location provided. Can't build URI.):
app/controllers/vote_controller.rb:8:in `vote'
And here's the method with the problem:
class VoteController < ApplicationController
def vote
question_id = params[:question][:id]
user_id = current_user.id
vote = Vote.where(["question_id = :q", { q: question_id }]).where(["user_id = :u", { u: user_id }]).take
respond_to do |format|
if vote.nil?
#vote = Vote.new
#vote.question = Question.find question_id
#vote.user = User.find user_id
#vote.save
votes = Vote.where(["question_id = :q", { q: question_id }]).count
format.json { render :json => { status: true, votes: votes } }
else
format.json { render :json => { status: false } }
end
end
end
end
Any clue of what's going wrong? And what can I do?
respond_with is meant to be used with a resource. Example
def show
#vote = Vote.find params[:id]
respond_with(#vote)
end
In your case, you need to use the respond_to method
def vote
# stuff
respond_to do |format|
if vote.nil?
# stuff
format.json { render json: { status: true, votes: votes } }
else
# other stuff
end
end
end

Pass attributes to method jQuery and Rails

I am trying to post data (jQuery ajax) to a custom method in my controller so that I can build dynamic database queries, I am taking values from a dropdown menu and using them as my search queries.
My method
class PublicController < ApplicationController
def rehomed(query={})
Animal.where(query).to_json
respond_to do |format|
format.js {render :json => {} }
end
end
end
Ajax call
$('select.btn').on('change', function() {
var animal_type = $('#animalType option:selected').text();
var animal_town = $('#animalTown option:selected').text();
$.ajax({
type: 'POST',
url: '/public/rehomed',
data: {
animal_type: animal_type
},
success: function(data) {
console.log(data);
}
});
});
So as an example if a user selects 'Cat' from the dropdown menu the query from my method should be
Animal.where(animal_type: 'Cat')
at the moment the query it is performing is
SELECT "animals".* FROM "animals"
which is just selecting every animal
How do I make this happen? what do I pass within {render :json => {} }
I'm trying to figure out how to put all this together.
You need to capture and pass the result of the query. Use params to get the param information from the request.
def rehomed
#animals = Animal.where(animal_type: params[:animal_type])
respond_to do |format|
format.js {render :json => #animals }
end
end
Or in one line
def rehomed
respond_to do |format|
format.js {render :json => Animal.where(animal_type: params[:animal_type])}
end
end
Note I'm not calling #to_json given that render :json will convert the query result to json.
Change jQuery to this:
$('select.btn').on('change', function() {
var animal_type = $('#animalType option:selected').text();
var animal_town = $('#animalTown option:selected').text();
$.ajax({
type: 'POST',
url: '/public/rehomed',
data: { 'query': { 'animal_type': animal_type } }, // or 'name': animal_name etc
success: function(data) {
console.log(data);
}
});
});
then in controller:
class PublicController < ApplicationController
def rehomed
respond_to do |format|
format.js { render :json => Animal.where(params[:query]) }
end
end
end
Note: queries as shown above may open a serious security issue, so do NOT do it unless you have a very strong reason or you know what you're doing.
If you don't change the jQuery shown above, then you will have to fetch the submitted value presented in params inside your controller like this :
def rehomed
respond_to do |format|
format.js { render :json => Animal.where(:animal_type => params[:animal_type]) }
end
end

Table disappears after AJAX function has run

For some reason after a click my button that requests data from my controller, my table disappears. Here is my table:
<div id="SelectedTm" style= float:right>
<table id = "PlyrsTm2" style = float:right>
<tr><th id="PTTitle" colspan=2>List of players on selected team</th></tr>
<tr><th id="PTHRows">Player</th><th id="PTHRows">Team</th></tr>
<% #pl.each do |f| %>
<tr><td class="player"><%= f.Plyr %></td><td class="team"><%= f.Team%></td></tr>
<% end %>
</table>
</div>
Here is the button that triggers my jquery with ajax
<button id="showbtn">Select Team</button>
Here is the jquery and ajax:
$(document).ready(function(){
$('#showbtn').on('click', function() {
ids = $('#teams').val()
IM = false
$.ajax({
url: "http://localhost:3000/teamplayers.json?resolution="+ids+"&import="+IM,
type:"get",
dataType: "json",
cache: true,
success:function(data){
$('#PlyrsTm2').html(data);
alert("Loading Players....");
},
error: function(error) {
alert("Failed " + console.log(error) + " " + error)
}
});
$('#PlyrsTm2').trigger('create');
return false;
});
});
Now as you can see, my table is populated by rails. Every time i select a new team the table disappears. And only re-appears if I reload the page, but that is the originally selected team, which by default is the first one.
UPDATE
Here is my controller:
class TeamplayersController < ApplicationController
before_filter :set_id
before_action :set_id, :set_teamplayer, only: [:show, :edit, :update, :destroy]
# GET /teamplayers
# GET /teamplayers.json
def index
#teamplayers = Teamplayer.all
#fteams = Fteam.all
tid = params[:resolution]
toimport = params[:import]
puts tid
if tid.nil? == true
tid = 1
#ids = tid
#pl = Teamplayer.joins(:live_player).where(:teamid => #ids).all
else
tid = tid.to_i;
#ids = tid
#pl = Teamplayer.joins(:live_player).where(:teamid => #ids).pluck(:Plyr, :Team)
end
if toimport == "true"
#turl = Fteam.where(:id => #ids).pluck(:TeamUrl)
#turl = #turl[0]
system "rake updateTm:updateA[#{#turl},#{#ids}]"
end
end
# GET /teamplayers/1
# GET /teamplayers/1.json
def show
end
# GET /teamplayers/new
def new
#teamplayer = Teamplayer.new
end
# GET /teamplayers/1/edit
def edit
end
# POST /teamplayers
# POST /teamplayers.json
def create
#teamplayer = Teamplayer.new(teamplayer_params)
respond_to do |format|
if #teamplayer.save
format.html { redirect_to #teamplayer, notice: 'Teamplayer was successfully created.' }
format.json { render action: 'show', status: :created, location: #teamplayer }
else
format.html { render action: 'new' }
format.json { render json: #teamplayer.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /teamplayers/1
# PATCH/PUT /teamplayers/1.json
def update
respond_to do |format|
if #teamplayer.update(teamplayer_params)
format.html { redirect_to #teamplayer, notice: 'Teamplayer was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #teamplayer.errors, status: :unprocessable_entity }
end
end
end
# DELETE /teamplayers/1
# DELETE /teamplayers/1.json
def destroy
#teamplayer.destroy
respond_to do |format|
format.html { redirect_to teamplayers_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_teamplayer
#teamplayer = Teamplayer.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def teamplayer_params
params.require(:teamplayer).permit(:playerid, :teamid)
end
end
So what is going wrong here, because i notice that it is calling every records individual page but why is it now giving my back the the information from my query as the data instead?
Looks like the statement ids = $("#teams").val(); will return undefined, since there is no element with id="teams".
If ids is undefined, it's likely that data is null or undefined in this function call:
function(data){
$('#PlyrsTm2').html(data);
alert("Loading Players....");
}
If data is null, calling html(null) will cause all your table data to disappear.
So, the solution is to populate ids correctly. I'm not sure what ids is supposed to do, but that's most likely the solution.
$('#PlyrsTm2').html(data);
That's why your table disappears
The problem is you're replacing the content of this element (not the element itself). To fix this, I'd do this:
$('#SelectedTm').html(data);

Categories

Resources