I'm working on a polymorphic activity feed, and try to put feed items from different model mixing in one page.
I have these following models
Feed items include
models relation
class User < ActiveRecord::Base
has_one :dashboard
has_many :activities
has_many :works
has_many :projects
has_many :project_records
end
class Work < ActiveRecord::Base
belongs_to :user
end
class Project < ActiveRecord::Base
belongs_to :user
has_many :project_records
end
class Dashboard < ActiveRecord::Base
belongs_to :user
has_many :activities
end
class Activity < ActiveRecord::Base
belongs_to :user
belongs_to :subject, polymorphic: true
end
I define feed in User model, a user can follow others feed.
def feed
following_ids = "SELECT followed_id FROM user_followings
WHERE follower_id = :user_id"
Activity.where("user_id IN (#{following_ids})
OR user_id = :user_id", user_id: id)
end
To build polymorphic activity feed, I have "after_create" in Work, Project, ProjectRecord model.
after_create :create_activity
private
def create_activity
Activity.create(
subject: self,
user: user
)
end
end
Then, I try to list feeds(work, project, project record) in dashboard(controller)/show(action) page.
Here is my dashboards controller
class DashboardsController < ApplicationController
before_action :authenticate_user!
before_action :only_current_user
def show
@feed_items = current_user.feed.order(created_at: :desc)
end
private
def only_current_user
@user = User.find( params[:user_id] )
redirect_to(root_url) unless @user == current_user
end
end
In dashboard/show view
<% if @feed_items.any? %>
<div class="feed-listing">
<% @feed_items.each do |feed| %>
<% if feed.subject_type == 'Work' %>
<%= link_to polymorphic_path(feed.subject) do %>
<%= render "activities/work_feed", subject: feed.subject, :feed => feed %>
<%#= feed.subject.title %>
<% end %>
<% elsif feed.subject_type == 'Project' %>
<%= link_to polymorphic_path(feed.subject) do %>
<%= render "activities/project_feed", subject: feed.subject, :feed => feed %>
<% end %>
<% else %>
<%= link_to polymorphic_path(feed.subject) do %>
<%= render "/activities/project_record_feed", subject: feed.subject, :feed => feed %>
<% end %>
<% end %>
<% end %>
</div>
<% end %>
I got error message "undefined method `project_record_path' for #<#:0x007f9368c63f88>"
I know the path is wrong, because ProjectRecord belongs to Project.
I try to use "project_project_record_path" to replace "polymorphic_path(feed.subject)", but it can't find project_id and project_record's id.
new_project_project_record GET /projects/:project_id/project_records/new(.:format) project_records#new
edit_project_project_record GET /projects/:project_id/project_records/:id/edit(.:format) project_records#edit
project_project_record GET /projects/:project_id/project_records/:id(.:format) project_records#show
If I remove the link_to helper(project_record), only
<%= render "/activities/project_record_feed", subject: feed.subject, :feed => feed %>
, dashboard/show page shows up, and other links work fine.
I want each ProjectRecord feed link to ProjectRecords/show page.
How to make this work?
To solve your routing problem you can use shallow routes:
resources :projects do
resources :project_records, shallow: true
end
This makes index
/new
/create
actions stay nested inside Project
, but show
/update
/destroy
go to the top level, as if resources were not nested.