ruby on rails - How to eager load in this case? -
class model runningtracks < activerecord::base has_many :achievements has_many :runners, through: :achievements class model runner < activerecord::base has_many :achievements has_many :running_tracks, through: :achievements class model achievement < activerecord::base belongs_to :runner belongs_to :running_tracks
on homepage there each do
list display runningtracks. next track display button mark run. eager loading solution includes
, references
(rails 4) in query in controller:
class runningtrackscontroller def index @running_tracks = runningtracks.includes(:achievements).references(:achievements) end
to improve usability, button next each record should not visible if had been marked. (will refactored in helper method)
@running_tracks.each |track| . - unless track.achievements.map(&:user_id).include? current_user.id = button_to "done", running_track_mark_as_done_path(track)
this works...but... database gets more records query lot of achievements, therefore custom association , includes
query achievements of current_user
(devise) should solution.
class model runningtracks < activerecord::base . has_many :achieved_runns, -> { user_id: current_user.id }, class_name "achievement"
but because current_user not accessible in model, not work. don't think possible pass variable hay_many association, it?
is there more efficient solution eager loading of all runningtracks including only achievements current user? thank valuable time!
the following ugly , breaks activerecord metaphor, give fast lookups db grew in size. maybe else can chime in way keep within eager-loading paradigm.
class runningtrack # returns set (for fast lookups) of track ids have @ least 1 achievement provided user def self.running_track_ids_for_achievements_for_user(user_id) set.new achievement.where(:user_id => user_id).pluck(:running_track_id) end end
then in controller:
class runningtrackscontroller def index @running_tracks = runningtracks.all @running_track_ids_for_achievements_for_user = runningtrack.running_track_ids_for_achievements_for_user(current_user.id) end end
and view:
- unless @running_track_ids_with_achievements_for_user.include? track = button_to "done", running_track_mark_as_done_path(track)
Comments
Post a Comment