Gugubaight Gugubaight - 2 months ago 6
Ruby Question

Rails 4: Target items through a model

I am fairly new to Rails and I have created the

FavoriteUser
model to allow users to favorite other users. That works fine. I'm showing the Favorited users of the current user on the
Tool
(another model)
Index
view.

Now I also want to show the Tools created by the Favorited User on that page, but I have no idea how to accomplish that.

class User < ActiveRecord::Base
has_many :tools
has_many :favorite_users # just the 'relationships'
# Favorite users of user
has_many :favorite_relationships, class_name: "FavoriteUser", foreign_key: "c_user_id"
has_many :userfavorites, through: :favorite_relationships, source: :user

# Favorited by a user
has_many :favorited_relationships, class_name: "FavoriteUser", foreign_key: "user_id"
has_many :userfavorited_by, through: :favorited_relationships, source: :c_user
end

class Tool < ActiveRecord::Base
belongs_to :user
end

class FavoriteUser < ActiveRecord::Base
belongs_to :c_user, class_name: "User"
belongs_to :user, class_name: "User"
end

class ToolsController < ApplicationController
def index
@favorites = current_user.favorites.order("created_at DESC")
@userfavorites = current_user.userfavorites.order("created_at DESC")
# adding '@userfavoritestools' or similar
@tools = Tool.where(user_id: current_user).order("created_at DESC")
@user = current_user
end
end

# app/views/tools/index.html.haml
%h2 My Favorite Tools
- @favorites.each do |tool|
= image_tag tool.cover_filename.url
%h2= link_to tool.title, tool
%p= tool.subtitle
%p= tool.tag_list
%p= tool.impressionist_count
%p= link_to tool.get_upvotes.size, like_tool_path(tool), method: :get
%p= link_to "Favorite", favorite_tool_path(tool, type: "favorite"), method: :get
%p= link_to "Unfavorite", favorite_tool_path(tool, type: "unfavorite"), method: :get
%p= link_to "Edit", edit_tool_path(tool)
%p= link_to 'http://ocubit.com/tools/'+tool.id.to_s
%p= time_ago_in_words(tool.created_at)

%h2 My Favorite Users
- @userfavorites.each do |user|
= image_tag gravatar_for user if user.use_gravatar == true
= image_tag user.avatar_filename.url if user.use_gravatar == false
%h2= link_to user.username, user
%p= link_to "Favorite", userfavorite_user_path(user, type: "favorite"), method: :get
%p= link_to "Unfavorite", userfavorite_user_path(user, type: "unfavorite"), method: :get
%p= user.tag_list


Adding a loop for the Newset Tools published by favorite users!



%h2 My Tools
- @tools.each do |tool|
= image_tag tool.cover_filename.url
%h2= link_to tool.title, tool
%p= tool.subtitle
%p= tool.tag_list
%p= tool.impressionist_count
%p= link_to "Edit", edit_tool_path(tool)
%p= link_to 'http://ocubit.com/tools/'+tool.id.to_s
%p= time_ago_in_words(tool.created_at)


Thanks in advance for any help!

Answer

If you are looking to get the @tools of the `current_user, try the following:

def index
  @favorites = current_user.favorites.order("created_at DESC")
  @userfavorites = current_user.userfavorites.order("created_at DESC")
  @tools = current_user.tools.order("created_at DESC")
  @user = current_user
end

If you instead are looking to get the @tools of the users that are of current_user's favorited users, then try the following:

def index
  @favorites = current_user.favorites.order("created_at DESC")
  @userfavorites = current_user.userfavorites.order("created_at DESC")
  @tools = Tool.where(user_id: @userfavorites.collect(&:id)).order("created_at DESC")
  @user = current_user
end

Or, you could move this logic into the User model and user that method, as follows:

class User < ActiveRecord::Base
  def tools_of_favorited_users
    Tool.where(user_id: userfavorites.collect(&:id))  
  end
end

def index
  @favorites = current_user.favorites.order("created_at DESC")
  @userfavorites = current_user.userfavorites.order("created_at DESC")
  @tools = current_user.tools_of_favorited_users.order("created_at DESC")
  @user = current_user
end
Comments