I have a story model that has many posts:
story.rb
:
has_many :posts, :dependent => :destroy
post.rb
:
belongs_to :story, :touch => true
I use AJAX to make a get request to my stories#index
action, and in that action I generate a response consisting of an array of Stories that conform to my search parameters. I include some additional data in my response, like whether or not there is a current_user
, and the date through which my the search looked for stories:
def index
ajax_response = {}
ajax_response[:currentUser] = user_signed_in? ? current_user : "no current user"
searched_through_date = Stories.last.created_at
@stories = get_stories(params,searched_through_date)
if @stories && @stories.length << 200
ajax_response[:stories] = @stories
ajax_response[:searched_through_date] = searched_through_date
else #only happens if there are too many responsive stories
ajax_response[:error] = {:type => "Response too large", :number_of_stories => @stories.length }
end
render :json => ajax_response
end
Now I want to change the response so that each story that I return has an additional attribute, :latest_post
, which consists of the most recent post belonging to that story. As a relative nOOb, I am having trouble modifying my story objects so that they include this new attribute/association, which is then rendered with the story object as part of the response.
Any help would be greatly appreciated!
EDIT:
Here is the relevant portions of the get_stories
method:
def get_stories(params)
q = get_story_search_params(params)
Story.search_with_params(q).limit(q[:limit]).offset(q[:offset])
end
def get_story_search_params(params)
q = {}
q[:limit] = params[:limit].blank? ? 25 : params[:limit].to_i
q[:text_to_search] = params[:text_to_search].blank? ? nil : params[:text_to_search]
q[:offset] = params[:offset].blank? ? 0 : params[:offset]
return q
end
I solved this problem with the help of the rabl gem. Coming up with the correct DSL syntax proved a little trial-and-error prone. The key was using object false
in the stories/index.json.rabl
view and making good use of rabl partials. In hopes that it might help someone out, I've attached my working code here.
#stories/index.json.rabl
object false
node(:currentUser) do
if user_signed_in?
partial('users/show', :object => current_user)
else
"no current user"
end
end
node(:stories) do
partial('stories/list', :object => @stories )
end
node(:searched_through_date) { |m| @searched_through_date }
#stories/show.json.rabl
object @story
attributes :address, :category, :created_at, :username
node :latest_post do |story|
{ :post => partial("posts/show", :object => story.posts.first) }
end
#stories/list.json.rabl
collection @stories, :object_root => "story"
extends "stories/show"
#user/show.json.rabl
object @user
node :user do |u|
{ :email => u.email, :username => u.username, :preferred_post_to_facebook => u.preferred_post_to_facebook,
:preferred_tweet_to_twitter => u.preferred_tweet_to_twitter, :home_address => u.home_address,
:home_lat => u.home_lat, :home_lng => u.home_lng, :suspended => u.suspended }
end