0

I'm trying to build a activity stream feature in my Rails/Angular app, for that I'm using the activity steam gem. I've tracked my movie model, so when a user adds a movie that action gets tracked.

This the activities controller,

activities = PublicActivity::Activity.order("created_at desc")
render :json => activities

I've added 2 movies, and the json output from activities looks like this,

{"id":3,"trackable_id":6,"trackable_type":"Movie","owner_id":1,"owner_type":"User","key":"movie.create","parameters":{},"recipient_id":null,"recipient_type":null,"created_at":"2015-12-30T12:31:24.765Z","updated_at":"2015-12-30T12:31:24.765Z"},
{"id":2,"trackable_id":5,"trackable_type":"Movie","owner_id":1,"owner_type":"User","key":"movie.create","parameters":{},"recipient_id":null,"recipient_type":null,"created_at":"2015-12-30T11:55:06.766Z","updated_at":"2015-12-30T11:55:06.766Z"},

The owner_id is the id of the user who added the movie. In the railscast Ryan uses this code to display the name

<% @activities.each do |activity| %>
  <div class="activity">
    <%= link_to activity.owner.name, activity.owner if activity.owner %>
  </div>
<% end %>

But because I'm using Angular I obviously can't use this code.

So I'm looking for a method to combine the user model and the activity model so the user data is also displayed in the json output.

So the expected result would be something like this,

{"id":3,"trackable_id":6,"trackable_type":"Movie","owner_id":1","name":Kees de Boer,owner_type":"User","key":"movie.create","parameters":{},"recipient_id":null,"recipient_type":null,"created_at":"2015-12-30T12:31:24.765Z","updated_at":"2015-12-30T12:31:24.765Z"},
{"id":2,"trackable_id":5,"trackable_type":"Movie","owner_id":1","name":Kees de Boer,"owner_type":"User","key":"movie.create","parameters":{},"recipient_id":null,"recipient_type":null,"created_at":"2015-12-30T11:55:06.766Z","updated_at":"2015-12-30T11:55:06.766Z"},

1 Answer 1

1

There are two ways to achieve what you want:

Method 1: — Including associations in a JSON Data

activities = PublicActivity::Activity.order("created_at desc")
render :json => activities.to_json( :include => { :user => { :only => :name } } ) 

and the result:

{ activity: { "id":3,"trackable_id":6,"trackable_type":"Movie", user: { name: "John Doe" } } 

This method will bring user name into JSON data, it's super easy, though the structure is a little bit different from what you are looking for.

Method 2: — Override as_json in Model

In this method you have to play some tricks in the model.

def owner
  user.name
end

def as_json(options = { })
  super((options || { }).merge({
    :methods => [:owner]
  }))
end

Override as_json function in your Activity model, then just call

render :json => activities.as_json

Now you will see owner_name appended in the new JSON data as you want.

{ activity: { "id":3,"trackable_id":6,"trackable_type":"Movie", owner: "John Doe" } 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.