0

I have a simple rails app and i am trying to add an activity feed on it. For that i am using the Public Activity Gem and was following the this Railscast

but now it's giving me an error:

undefined method `shipment' for #<Shipment:0x6a96578>

My codes are:

activities_controller.rb

class ActivitiesController < ApplicationController
  def index
    @activities = PublicActivity::Activity.order("created_at desc")
  end
end

My Activity index.html.erb file

<h1>feeds</h1>
<% @activities.each do |activity| %>
  <div class="activity">
    <%= link_to activity.owner.full_name, activity.owner if activity.owner %>
    added comment to <%= link_to activity.trackable.shipment.name.activity.trackable.shipment %>
    </div>
    <% end %>

My comment.rb file

class Comment < ActiveRecord::Base
include PublicActivity::Model
 tracked owner: ->(controller, model) { controller && controller.current_user }
  belongs_to :shipment
  belongs_to :user
end

I have a simple rails app and i am trying to add an activity feed on it. For that i am using the Public Activity Gem and was following the this Railscast

but now it's giving me an error:

undefined method `user_path' for #<#:0x4a90a30>

My codes are:

activities_controller.rb

class ActivitiesController < ApplicationController
  def index
    @activities = PublicActivity::Activity.order("created_at desc")
  end
end

My Activity index.html.erb file

<h1>feeds</h1>
<% @activities.each do |activity| %>
  <div class="activity">
    <%= link_to activity.owner.full_name, activity.owner if activity.owner %>
    added comment to <%= link_to activity.trackable.shipment.name.activity.trackable.shipment %>
    </div>
    <% end %>

My comment.rb file

class Comment < ActiveRecord::Base
include PublicActivity::Model
 tracked owner: ->(controller, model) { controller && controller.current_user }
  belongs_to :shipment
  belongs_to :user
end

My routes.rb file

Rails.application.routes.draw do

  get 'activities/index'

  get 'profiles/show'
  get 'pages/homepage'


  devise_for :users, :controllers => {:registrations => "registrations"}
  resources :shipments do
    member do
      get "like", to: "shipments#upvote"
    end
    resources :comments
  end
  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".
  root "shipments#index"
  get '/:id', to: 'profiles#show'



  get "mailbox/inbox" => "mailbox#inbox", as: :mailbox_inbox
  get "mailbox/sent" => "mailbox#sent", as: :mailbox_sent
  get "mailbox/trash" => "mailbox#trash", as: :mailbox_trash
    resources :conversations do
    member do
      post :reply
      post :trash
      post :untrash
      resources :users
    end
  end
end

stack trace

  Rendered activities/index.html.erb within layouts/application (31.2ms)
Completed 500 Internal Server Error in 109ms (ActiveRecord: 78.0ms)

ActionView::Template::Error (undefined method `shipment' for #<Shipment:0x4dc44b
0>):
    2: <% @activities.each do |activity| %>
    3:   <div class="activity">
    4:     <%= link_to activity.owner.profile_name, activity.owner if activity.o
wner %>
    5:     added comment to <%= link_to activity.trackable.shipment.name, activi
ty.trackable.shipment %>
    6: <% end %>
  app/views/activities/index.html.erb:5:in `block in _app_views_activities_index
_html_erb___51428318_40366872'
  app/views/activities/index.html.erb:2:in `_app_views_activities_index_html_erb
___51428318_40366872'
Ahmed Reza
  • 293
  • 1
  • 3
  • 19
  • Why on earth are you calling `activity.trackable.shipment.name.activity.trackable.shipment`? If you want to get the object linked to an activity you just need to do `activity.trackable`. – max Oct 07 '15 at 14:36
  • because it was shown in the railscasts...and i want to add a link to the show of the shipment where comment have been made @max – Ahmed Reza Oct 09 '15 at 03:29
  • I think you are missing a comma. `<%= link_to activity.trackable.name, activity.trackable %>`. In the railscast he is going from a Comment, to the Recipe which it belongs. – max Oct 09 '15 at 07:20
  • that's the same thing am trying to do here am trying to go from a Comment, to the shipment which it belongs... and by the way sir @max after adding the comma it's giving me the error undefined method `comment_path' for #<#:0x4b09858> this is what i used <%= link_to activity.trackable.shipment.name, activity.trackable %> Any help?? Sir – Ahmed Reza Oct 09 '15 at 12:19

1 Answers1

1

What Ryan fails to mention in the Railscast is that you may get activities belonging to different types of trackables.

So if you have set up tracking for the shipment model:

class Shipment < ActiveRecord::Base
  include PublicActivity::Model
  tracked
  # ...
  belongs_to :user
  has_many :comments, dependent: :destroy
end

And created a few shipment records and a few commends than your activities table will contains something like this

id  trackable_type # ...
1   Shipment
2   Shipment
3   Comment

Here are two possible solutions:

1. Filter the query for one type of trackable.

 @activities = PublicActivity::Activity.order("created_at desc")
                 .where(trackable_type: "Comment")

2. Use different partials for each type of trackable:

<% @activities.each do |activity| %>
  <%= render partial "activities/#{ activity.trackable.model_name.singular }", 
     activity: activity, 
     object: activity.trackable,
     owner: activity.owner
  %>
<% end %>

What this does is render app/views/activities/_comment.html.erb or _shipment.html.erb depending on the type. We also setup some local variables so that we don't have to write activity.foo.bar.baz.

We also use the object option which creates an instance variable (an @ variable) with the same name as the partial. So in it would be @shipment in _shipment.html.erb.

So in your _comment.html.erb you would do:

<div class="activity">
  <%= link_to owner.full_name, owner if owner %>
  added comment to <%= link_to @comment.shipment.name, @comment.shipment %>
</div>

See also:

max
  • 96,212
  • 14
  • 104
  • 165