How to json response according to search params - ruby-on-rails

I want to get json response according to filters. Now on page load I'm getting json response for the every properties which are listed in that page.
In the same page I have filters, so if I search property through filters according to that json response should change.
class PropertiesController < ApplicationController
def index
if params[:city].present?
#properties=Property.where("properties.city = ? ",params[:city],"%#{params[:city]}%")
elsif params[:cityname].present?
#properties=Property.where("properties.city = ? ",params[:cityname])
else
#properties = Property.where("properties.status = ?", '1')
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #properties.as_json(only: [:id, :latitude, :longitude]) }
end
end
end
What is wrong with my code?

Related

"param is missing or the value is empty: color" error in controller

I followed a tutorial on YouTube involving making a simple model, printing out the results and updating the model with a form and did a find and replace for what I was trying to accomplish ("text files, the tutorial involved images)
Everything worked up until around the time I just wanted an single index page and tried merging all the controller logic into the index.
I'm currently getting an error reading param is missing or the value is empty: color on params.require in the controller below.
class ColorsController < ApplicationController
before_action :find_color, only: [:destroy]
def index
#colors = Color.all.order("created_at DESC")
#color = Color.new(color_params)
end
def destroy
#color.destroy
end
private
def find_color
#color = Color.find(params[:id])
end
def color_params
params.require(:color).permit(:file)
end
end
What I take from this is that it's not recognizing the #color instance variable, but I don't know or why I'm supposed to rectify this.
Model:
class Color < ActiveRecord::Base
has_attached_file :file
validates_attachment_content_type :file, :content_type => ["application/xml"]
end
Form:
= simple_form_for #color do |f|
= f.input :file
= f.submit
Explanation of what I'm doing wrong is much appreciated.
param is missing or the value is empty: color
You should change your index method to below
def index
#colors = Color.all.order("created_at DESC")
#color = Color.new #notice the change here
end
Also, you should define a create method like below
def create
#color = Color.new(color_params)
respond_to do |format|
if #color.save
format.html { redirect_to #color, notice: 'Color was successfully created.' }
format.json { render :show, status: :created, location: #color }
else
format.html { render :new }
format.json { render json: #color.errors, status: :unprocessable_entity }
end
end
end

Rails caching gives wrong response format

I am using ETag caching for a Rails (4.1.1) action with the stale? method; however it does not take the request format into consideration. Example: if /stations.json has been loaded by the user and they then click a link to /stations they will get a cached JSON response instead of html.
Am I doing it wrong or is this a Rails bug?
# GET /stations
# GET /stations.json
def index
#title = "Stations"
#last_updated = Station.order("updated_at asc").last
if stale?(#last_updated, last_modified: #last_updated.try(:updated_at))
#stations = all_with_latest_observation
respond_to do |format|
format.html
format.json { render json: #stations }
end
end
end
I think you should add the key :etag when you call stale? method.
# GET /stations
# GET /stations.json
def index
#title = "Stations"
#last_updated = Station.order("updated_at asc").last
if stale?(etag: #last_updated, last_modified: #last_updated.try(:updated_at))
#stations = all_with_latest_observation
respond_to do |format|
format.html
format.json { render json: #stations }
end
end
end
Then let's see what's happen!
This seems to be a bug in ActionPack
I found a workaround
class ApplicationController
etag { request.format }
end
And of course the spec:
describe StationsController do
describe "GET index" do
describe "ETag" do
before { get :index, format: 'json' }
it "should not use the same ETag for different content types" do
get :index, format: 'json'
first_response = response.headers.clone
get :index, format: 'html'
expect(first_response['ETag']).to_not eq (response.headers['ETag'])
end
end
end
end

Rails - How to render json with extra field in index controller method

I'm using Rails 4.0.2 with paperclip for image upload in my project. Also I need to send a full image path of paperclip. So I can do it with add new field and set image path manually in my show controller method for particular record.
show
def show
respond_to do |format|
format.html
format.json { :json => JSON::parse(#demo.to_json.merge("new_field" => #demo.image_url.url).to_json}
end
end
When I view Json for any of my record, this is will showing good.
{
id: "1",
name: "demo",
new_field: "/demo/1/original/file.jpg"
}
In same scenario, I need to get the full image path of paperclip image for all records when I am requesting to index method on controller
index
def index
#demos = Demo.all
respond_to do |format|
format.html
format.json { :json => Demo.all.to_json}
end
end
I tried some of codes, but I don't know how exactly to write
def index
#demos = Demo.all
#demos.each do |demo|
new_field = {"new_field" => #demo.image_url.url}
# After I stucked with logic, how to uppend with 'demo'.
end
respond_to do |format|
format.html
format.json { :json => Demo.all.to_json}
end
end
How do I iterate my individual Demo model and How to merge full image path into each record.
I found the solution for my question,
def index
#demos = Demo.all
#demos_data = []
#demos.each do |demo|
new_field = {"new_field" => #demo.new_field.url}
demo = JSON::parse(demo.to_json).merge(new_field)
#demos_data << demo
end
respond_to do |format|
format.html
format.json { :json => #demos_data}
end
end
I suggest you to use two approaches, 1)use active model serializer to expose json response. 2) use jbuilder library to expose custom fields. Still you need help please let me know.
Try this:-
def index
#demos = Demo.all
#demos_data = []
#demos.each do |demo|
demo["new_field"] = #demo.image_url.url
#demos_data << demo
end
respond_to do |format|
format.html
format.json { :json => #demos_data}
end
end
maybe you can try:
def index
#demos = Demo.all
#demos.map do |demo|
new_field = {"new_field" => #demo.image_url.url}
demo.attributes.merge(new_field)
end
respond_to do |format|
format.html
format.json { :json => #demos}
end
end
attributes method returns a hash of all the object attributes, just need merge new key-value into the returned hash.
Another way of doing it is in your controller where you are rendering the json
render json: #merchants,
include: {
offers: {
except: [:created_at, :updated_at],
include: {
categories: {
except: [:created_at, :updated_at]
}
}
},
location: {
methods: :country_name,
except: [:created_at, :updated_at]
}
},
except: [:created_at, :updated_at]
Note the methods: :country_name, there you can render methods from your model as json attributes. and through include: ... you can eager load and render related models.

Rails - Add index key for json parsed value

I am using rails 4.0.2. For my mobile api, I need to send JSON values to that. Here I face some problems to sending JSON . I want to customize my JSON with index key
For example, when I request index of my cities controller,
http:localhost:3000/cities.json
I got JSON value like this,
[
{"id":1,"name":"AAAA"},
{"id":2,"name":"BBBB"},
{"id":2,"name":"CCCC"}
]
But I want to surrounded with some named object or array.
{
"cities" :
[
{"id":1,"name":"AAAA"},
{"id":2,"name":"BBBB"},
{"id":2,"name":"CCCC"}
]
}
Now I tried in my controller,
def index
#cities = City.all
respond_to do |format|
format.html
format.json{ render :json => #cities.to_json(:methods => [:image_url]) }
# :methods => [:image_url] this is related to paperclip gem
end
end
Try this first as:-
def index
#cities = City.all
cit ={'cities' => #cities}
respond_to do |format|
format.html
format.json{ render :json => cit}
end
end
After that try as:-
def index
#cities = City.all
cit ={'cities' => #cities}
respond_to do |format|
format.html
format.json{ render :json => cit.to_json(:methods => [:image_url]) }
end
end

How do I override Kaminari pagination when rendering JSON in the respond_to block?

I want to override Kaminari's pagination when rendering JSON, or tell it to return all with pagination.
In App1, I am using ActiveResource to access App2's Group model:
class Group < ActiveResource::Base
self.site = "http://www.app2.com:3000"
end
Here's App2's Group model:
class Group < ActiveRecord::Base
default_scope order('name asc')
paginates_per 10
This is my controller. The Group.search stuff is ransack:
class GroupsController < ApplicationController
# GET /groups
# GET /groups.json
def index
#search = Group.search(params[:q])
#groups = #search.result.page params[:page]
respond_to do |format|
format.html # index.html.erb
format.json { render json: #groups }
end
end
I've added eleven groups to App2. In the console of App1 I get:
[45] pry(main)> Group.all.count
=> 10
What is the best way to do this without changing the HTML pagination rendering?
You can prepare all the common logic you need but only apply pagination for the HTML format:
def index
#search = Group.search(params[:q])
#groups = #search.result
respond_to do |format|
format.html { #groups = #groups.page(params[:page]) }
format.json { render :json => #groups }
end
end
You can run different code in different formats:
def index
respond_to do |format|
format.html {
#search = Group.search(params[:q])
#groups = #search.result.page params[:page]
} # index.html.erb
format.json {
render json: Group.all
}
end
end

Resources