rails json filter ":only" - ruby-on-rails

I did the following query on my model:
output = user.interests.includes([:culture, :sports])
This gives me all the "interests" with all the "culture" and "sports" entries of the user.
I'd like to forward only the id column for "interests", "culture" and "sports" to the client as json.
I tried doing it this way:
output.to_json(:include => [:culture, :sports], :only => ['id'])
When doing it that way it only shows the IDs of the interests but still includes every column of "culture" and "sports". What do I have to add to restrict "culture" and "sports" also to only the IDs?
Thanks in advance!

You can add options for each of the includes by using a separate hash, e.g:
output.to_json(:include => { :culture => { :only => :id }, :sports => { :only => :id } }, :only => ['id'])

Related

The usage of includes method for Ruby on Rails

I don't understand what {article: :categories} means for the below code.
I have read the documentation, but it does not show an example like includes(z => {x: :y}). Can somebody put this to a different form that I can understand? What exactly is x: :y?
#articles = ArticleBase.includes(media.to_sym => { article: :categories })
In addition, if I want to add another condition to it (.includes(media.to_sym => :article)), would the code below be alright syntax-wise?
#articles = ArticleBase.includes(media.to_sym => { article: :categories }, media.to_sym => :article)
Whats happening here is that they are just dynamically assigning a hash key in the hash that's provided as an argument to #includes:
"foo".then do |media|
{ media.to_sym => { article: :categories }}
end
=> {:foo=>{:article=>:categories}}
This is possible when you are using the hash rocket hash syntax but not the colon syntax.
{ media.to_sym: bar } # Raises a SyntaxError
would the code below be alright syntax-wise?
#articles = ArticleBase.includes(media.to_sym => { article: :categories }, media.to_sym => :article)
Not really. It won't raise a syntax error but neither will it do what you're intending. When you have a hash literal with duplicate keys Ruby does not warn you - it just overwrites with the last given value for the key.
"foo".then do |media|
{ media.to_sym => { article: :categories }, media.to_sym => :acticle }
end
# => {:foo=>:acticle}
Its also unclear what this code even is supposed to accomplish since { article: :categories } will include article.

Serialize and deserialize ActiveRecord model with children

Form has many entries. To serialize form and it's entries I use:
json = #form.to_json( { :only => Form.accessible_attributes.to_a, :include => {:entries => {:only => Entry.accessible_attributes.to_a}}})
Form and entries attributes can be modified or deleted while they are in JSON.
To deserialize I use (but not working) :
#form = #form.from_json(json)
#form.save
How to save entries at once with form?
Had to change entries to entries_attributes:
json = #form.to_json( { :only => Form.accessible_attributes.to_a, :include => {:entries => {:only => Entry.accessible_attributes.to_a}}}).gsub('"entries":[{', '"entries_attributes":[{')

Rewrite JSON structure and include an EACH loop in Rails

I have a list of shows in a database that need to be output in a certain JSON style in order to work with Polymaps.
Part of this includes the need to iterate over one section in order to create a list of points. I'm pretty certain that this needs to be achieved using :include in the render :json => #results bit of the code.
Here's the code as it stands:
def gigs
#gigs = Show.where(:displayname => "Vans Warped Tour 2011")
#giggage = [{
:type => "FeatureCollection",
:features => [
#gigs.each do |gig|
:type => "feature",
:geometry => {
:coordinates => [
gig['lng'],
gig['lat']
],
:type => "Point"
},
:properties => gig
end
]
}]
render :json => #giggage
end
There's an each loop inside a hash which I know you can't do, but that's the best way to illustrate what I'm going for, I'm going in circles on this.
I did try this which got me some of the way there, but only returned the one result because of the structure of the loop:
def gigs
#gigs = Show.where(:displayname => "Vans Warped Tour 2011")
#gigs.each do |gig|
#gigs_to_render = {
:type => "FeatureCollection",
:features => [
:type => "feature",
:geometry => {
:coordinates => [
gig['lng'],
gig['lat']
],
:type => "Point"
},
:properties => gig
]
}
end
render :json => #gigs_to_render
end
Thanks for your help! Anyone. Everyone!
The code as it stands should be very close to working. Just change each to map and surround the body of the block in curlies so it all gets returned as a hash for each gig.

Specifying a param from a route

Consider a PersonController which has a list action. A user can choose to list all people, or only males or females; currently, to do that, they'd have to go to /people/m or /people/f, corresponding to the route
map.list_people "people/:type",
:conditions => { :method => :get },
:requirements => { :type => /a|m|f/ },
:defaults => { :type => 'a' }
(/people/a works the same as just /people/, and lists all people).
I want to change my routing so that I could have two routes, /males/ and /females/ (instead of people/:type), both of which would go to PersonController#list (DRY -- aside from an extra parameter to what's being searched, everything else is identical), but will inherently set the type -- is there a way to do this?
map.with_options(:controller => "people", :action => "index") do |people|
people.males 'males', :type => "m"
people.females 'females', :type => "f"
end
Then you should be able to do males_path or males_url to get the path for this, and I'm sure you can guess what you do to get the path to females.

Rails: Database records with custom route...?

I have a model, target, that holds a number of records that are timestamped. On the corresponding controller, I list the months of those records by doing the following:
In models/target.rb
def month
self.recorded_on.strftime('%B')
end
In controllers/targets_controller.rb
#records = Target.find :all
In views/targets/index.html.haml
%ul
- #records.group_by(&:month).sort.each do |month, data|
%li= link_to month, ''
That all works great for listing the available months for the records that I have. Next, I want to be able to click on the month and get a report of all the records for that month, at the following path generated with year and the month: /targets/2009/04
How would I do this?
Add some named scopes to your Target model to support finding by year and by month number. Something like:
class Target < ActiveRecord::Base
named_scope :by_month,
lambda { |month| { :conditions => ['MONTH(recorded_on) = ?',
month] }}
named_scope :by_year,
lambda { |year| { :conditions => ['YEAR(recorded_on) = ?', year] }}
.
.
.
end
(Note that the conditions here are using MySQL syntax.)
Assuming you're using RESTful routes, set up a named route like the one below in your config/routes.rb file (make sure it's declared before the default route):
map.targets_by_month '/targets/:year/:month', :controller => 'targets',
:requirements => { :year => /\d{4}/, :month => /\d{1,2}/ },
:conditions => { :method => :get }
—You can use this route in your view like this:
<%= link_to 'Show April 2009 Targets', targets_by_month_path('2009', '04') %>
(Note that the leading zero for the month is optional because of the :requirements regular expression in the named route defined above)
Finally, in your TargetsController, set up the index action to use the named_scopes defined earlier:
def index
#records = Target.by_year(params[:year]).by_month(params[:month])
.
.
.
end

Resources