Pass attributes to method jQuery and Rails - javascript

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

Related

Select2 Autocomplete & Tagging not working Rails 5

I'm building a rails 5 App and integrating a Tagging feature using acts_as_taggable_on, select2, and simple_form gems.
So essentially what I'm trying to do is tag a product on the new product form, if the tag exists in an autocomplete dropdown box then use the existing tag, if not create the tag.
Right now, I'm at a bit of loggerhead and not sure where I'm going wrong.
All that I get on the form is an empty multi-select box (below)
this should appear as a text field with a dropdown that fills as the user enters in the tag names.
Product Controller "new" and "create" actions and the product_params method:
def new
#product = Product.new
respond_to do |format|
format.html
format.json { render json: #product }
end
end
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.valid?
#product.save
format.html { redirect_to #product, flash: { success: "#{#product.name.titleize} has been created & added to the store." } }
format.json { render json: #product, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
def product_params
params.require(:product).permit(:name, :description, :price, :tag_list, tag_list: [])
end
My Js:
// JS Initializer
$(document).on('turbolinks:load', function() {
// Select2 Tag Creation
$('.multiple-input').each(function() {
$(this).select2({
tags: true,
tokenSeperators: [','],
theme: 'bootstrap',
placeholder: 'seperated by space'
});
});
// Select2 Autocomplete
$('#product-autocomplete').select2({
ajax: {
url: "/products.json",
dataType: json,
results: function(data, page) {
return {
results: $.map( data, function(product.tag_list, i) {
return { id: product.id, text: product.tag.name }
} )
}
}
}
});
});
My simple_form input:
<%= f.input :tag_list, input_html: { class: 'multiple-input', id: 'product-autocomplete', multiple: "multiple"}, collection: #product.tag_list %>
I've tried a few other ways of implementing this with no luck, I think this is going to really boil down to the JS, and that is my Achilles heel. I'm learning but really struggling with this. Any assistance here would be greatly appreciated! Please if I have missed any pertinent info let me know I'll be happy to post!
EDIT 1:
Im adding a pic of the error my google inspect console is spitting out.
Note: the url: reads /products.json not the #product shown in the image.
So I needed to do a few things to hook this all up..
1. Add Tags Controller and a resource route to call the tags_list
class TagsController < ApplicationController
def index
tags = ActsAsTaggableOn::Tag
.where("name ILIKE ?", "%#{params[:term]}%")
.select("id, name as text")
respond_to do |format|
format.json {render json: tags}
end
end
end
resources :tags, only: [:index]
2) Fix JS to populate the autocomplete dropdown:
// JS Initializer
$(document).on('turbolinks:load', function() {
// Select2 Tag Creation
$('.multiple-input').each(function() {
$(this).select2({
tags: true,
tokenSeperators: [','],
theme: 'bootstrap',
placeholder: 'seperated by space',
minimumInputLength: 3,
ajax: {
url: "/tags.json",
dataType: 'json',
processResults: function(data) {
console.log(data)
return {results: data};
}
}
});
});
});

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

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);

use JSON object with rails scoped

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.

Categories

Resources