going directly to my problem.
render :json => projects.to_json(:only => ['name', 'id'],:include => {:client => {:only => ['name']}, :deliverables => {:only => ['name', 'id'], :include => {:tasks => {:only => ['name','id']} } } })
This is how my controller responds for json request. Now my problem is that it lists all the deliverables & tasks that are in given project but here I want to respond with tasks & deliverables that meets certain condition like all that are created in specific month.
Thanks is advance.
Here's what I did, in project model
has_many :uncompleted_deliverables,
:class_name => 'Deliverable',
:conditions => 'completed = false'
The same applies to deliverable model
has_many :uncompleted_tsks, :class_name => 'Task', :conditions => 'completed = false'
And then responded json in following way,
format.json { render :json => projects.to_json(:only => ['name', 'id'],
:include => {:client => {:only => ['name']}, :uncompleted_deliverables => {:only => ['name', 'id'], :include => {:uncompleted_tsks => {:only => ['name','id']} } } }) }
Anyway thanks guys for your response..
Could you just include a proc? (see end of documentation here)
I guess the code could look something like that:
in you Project model:
def to_json(options={})
tasks_json = Proc.new { |options|
options[:builder].tasks do
selected_tasks = tasks.select {|t| t.created_at > 30.days.ago } # or whatever your condition is
selected_tasks.each do |t|
options[:builder].task do
options[:builder].tag!('id', t.id)
options[:builder].tag!('name', t.name)
end
end
end }
options.merge!(:procs => [tasks_json])
end
Would that work for you?
Related
I have the code like following
Listing.search(
Riddle::Query.escape(params[:search]),
:include => params[:include],
:page => page,
:per_page => per_page,
:star => true,
:with => with,
:with_all => with_all,
:order => params[:sort]
)
params[:include] contains the value like [:listing_images, :author, :category, :origin_loc]
I don’t know what was wrong here.
Is there a way to exclude properties from :jobs like I've done with #databases? I'm new to ruby and rails so I suspect (read: hope) that my syntax is wrong and this is an easy problem to fix.
wants.json { render :json => #databases, :include => [:jobs], :except => [:id, :created_at, :updated_at] }
If your #databases object's model class has_many :jobs then, you can do:
render :json => #databases.to_json(:include => {:jobs => {:except => [:created_at, updated_at]}}, :except => [:id, :created_at, :updated_at])
Solution
Added => { :except => [:id] } to :jobs
wants.json { render :json => #databases, :include => [:jobs => { :except => [:id] }, :except => [:id, :created_at, :updated_at] }
I need to render as Json a complex structure. I have next structure working:
render :json => #booking, :include => [:paypal,
:boat_people,
:boat => {:only => :boat_model, :include => {:boat_model => {:only => :name, :include => { :boat_type => {:only => :name}}}}}]
but I´m not able to add a port attribute with some other nested attributes to :boat, such as :boat_model (at same level).
UPDATE:
Although it´s not working, I include my port attribute.
render :json => #booking, :include => [:paypal,
:boat_people,
:boat => {:only => [:boat_model => {:include => {:boat_model => {:only => :name, :include => { :boat_type => {:only => :name}}}}},
:port => {:include => :city => {:only => name}}]}]
I mean, boat_model and port are both boat attributes.
This is the model object:
class Boat < ActiveRecord::Base
attr_accessor :price
#price
attr_accessor :extrasPrice
#extrasPrice
def as_json(options = { })
h = super(options)
h[:price] = #price
h[:extrasPrice] = #extrasPrice
h
end
belongs_to :boat_model
belongs_to :port
belongs_to :state
has_many :photos
end
I got it.
render :json => #booking, :include => [:paypal,
:boat_people,
:boat => {:only => :name, :include => {:port => {:only => :name, :include => {:city => {:only => :name, :include => {:country => {:only => :name}}}}},
:boat_model => {:only => :name, :include => {:boat_type => {:only => :name}}}}}]
You are probably going to want a much more robust system for displaying JSON. The built-in Rails helpers are really designed primarily for simple additions that enable users to do most of what they would want to accomplish. However, in your case, you are trying to make it do more than it was designed for.
I would highly recommend either creating a view object or using a gem like RABL.
My preference is to use Rabl for complex JSON. It basically creates the 'view object' for you by building a domain specific language that makes it relatively easy to build complex JSON objects in rails.
RABL basically allows you to build views that format JSON instead of HTML. The DSL is extremely rich and enables you to do just about anything you would want. In your case, I think the code would look something like this:
app/views/bookings/show.rabl
object #booking
#these are attributes that exist on your booking model:
attributes :booking_attribute, :other_booking_attribute
child :paypal do
#these are attributes that exist on your paypal model:
attributes :paypay_attribute1, :other_paypal_attribute
end
child :boat_people do
#boat_people attributes that you want to include
attributes :blah_blah
end
child :boat do
#boat attributes that you want to include
attributes :boat_attribute1, :boat_attribute2
child :boat_model do
attributes :name
child :boat_type do
attributes :name
end
end
end
There is a mass assignment defined in sys_log model in our rails 3.1.4 app:
attr_accessible :log_date, :user_name, :user_id, :user_ip, :action_logged, :as => :new_log
A method is defined in application_controller to save the log:
def sys_logger(action_logged)
log = SysLog.new(:log_date => Time.now, :user_id => session[:user_id], :user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged, :as => :new_log)
log.save
end
However, the mass assignment does not work. Here is the warning message:
WARNING: Can't mass-assign protected attributes: log_date, user_id, user_name,
user_ip, action_logged, as
:new_log is not working as defined. What's wrong with the code above? Thanks so much.
The :as => :new_log is now part of the hash of attributes, instead of a separate option you pass in.
Adding some curly braces should help:
def sys_logger(action_logged)
log = SysLog.new({:log_date => Time.now, :user_id => session[:user_id],
:user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged }, :as => :new_log)
log.save
end
Or assigning it temporarily:
def sys_logger(action_logged)
attrs = { :log_date => Time.now, :user_id => session[:user_id],
:user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged }
log = SysLog.new(attrs, :as => :new_log)
log.save
end
Using ROR 2.3.8
I have this in cities_controller.rb:
#shops = Shop.published.search params[:keyword], {
:conditions => conditions,
:star => true,
:group_by => 'city_id',
:group_function => :attr,
:page => params[:page]
}.merge(:order => 'rating_average DESC')
#cities = #shops.collect { |shop| shopy.city }
How can I tell Rails to get the rating_average from City model instead of Shop model? Because the Shop model does not have rating_average. It's actually City model that gets rated.
Thank you.
UPDATES
published namescope in Shop.rb
sphinx_scope(:published) {
{:conditions => {:status => 'published'}}
}
Indexes in Shop.rb
define_index do
indexes city.name, :as => :name, :sortable => true
indexes city.duration, :as => :duration
indexes city.status, :as => :status
#has city.budget, :as => :budget
#has city(:created_at), :as => :created_at
has city(:rating_average), :as => :rating_average
has city_id
end
UPDATES 2
class City < ActiveRecord::Base
has_many :shops, :dependent => :destroy
...
end
You should use joins to acheive this:
#shops = Shop.published.search params[:keyword], {
:conditions => conditions,
:star => true,
:group_by => :city_id,
:group_function => :attr,
:page => params[:page]
}.merge(:order => :rating_average,
:sort_mode => :desc)
You should also add cities. or shops. before columns to specify which table's column.