Working with Exported Data from API
I’m building a leaderboard that displays the Team.name of each team as well as the users who have picked that particular team as their favorites. I’m also populating another attribute Favorite.points; to display the users with the most points accumulated for that respective team.
Here are the models I’m working with:
Favorite.rb
class Favorite < ActiveRecord::Base
belongs_to :users
belongs_to :teams
end
Team.rb
class Team < ActiveRecord::Base
has_many :favorites
has_many :users, :through => :favorites
end
User.rb
class User < ActiveRecord::Base
has_many :favorites
has_many :teams, :through => :favorites
end
To start this process, I’m trying to match up the id’s that are common between Team.external_id and Favorite.team_id (the same is the case for User.external_id => Favorites.user_id). I can use Team.find_all_by_external_id(3333) to get the IDs of all Team objects that have an external_id of ‘3333’and the same goes for Favorite.find_all_by_team_id.
What’s the next best step for me to obtain/show the data I’m looking for? Is a SQL join clause best? Or is it better to write if statements matching up values and iterating through the JSON arrays?
Any help is appreciated, thanks!
This will get you all the favorites whose
team_idmatches theexternal_idattribute of a row in theteamstable, for a specific team (here, the team with id3333):The tricky thing here, as I mentioned in my comments, is that you are going entirely against the grain of rails associations when you match the external id on the
Teammodel (an attribute which you have created) to theteam_idon theFavoritemodel (which is used throughout rails to get and assign associations).You will see the problem as soon as you try to actually get the team for the favorite you find in the above join:
What’s going on here? If you look closely at the query, you’ll see that rails is selecting teams whose
idis 3333. Note that it is not looking for teams whose external id is 3333, which is what you want.The fundamental problem is that you are trying to use external ids (ids specific to your API) for associations, which won’t work. And indeed, there is no reason to do it this way.
Instead, try this:
This will get you all favorites whose teams have the external id 3333. Note that Rails will do this by joining on
teams.id = favorites.team_id, then filtering byteams.external_id:You can do the same thing the other way around:
which will generate the SQL:
Note again that it is the
idthat is being used in the join, not the external id. This is the right way to do this: use the conventionalidfor your associations, and then just filter wherever necessary by your (custom-defined, API-specific) external id.Hope that helps!
UPDATE:
From the comments, it seems that the
team_idon yourFavoritemodel is being defined from the API data, which means that the id corresponds to theexternal_idof yourTeammodel. This is a bad idea: in rails, the foreign key<model name>_id(team_id,user_id, etc.) has a specific meaning: the id is understood to map to theidfield of the corresponding associated model (Team).To get your associations to work, you need to use ids (not external ids) for associations everywhere (with your
Usermodel as well). To do this, you need to translate associations defined in the API to ids in the rails app. When you add a favorite from the API, find the Teamidcorresponding to the API team id.So you are assigning the
idof the team with a given external id. You need to query the DB for each favorite you load from the API, which is potentially costly performance-wise, but since you only do it once it’s not a big deal.