Class: RecsysNeedsFinder
- Inherits:
-
Object
- Object
- RecsysNeedsFinder
- Defined in:
- app/workers/recsys_needs_finder.rb
Instance Attribute Summary collapse
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Instance Method Summary collapse
- #call ⇒ Object
- #get_score ⇒ Object
-
#initialize(user_id) ⇒ RecsysNeedsFinder
constructor
A new instance of RecsysNeedsFinder.
- #latest_needs ⇒ Object
- #list_recommended_needs ⇒ Object
- #needs_ids ⇒ Object
Constructor Details
#initialize(user_id) ⇒ RecsysNeedsFinder
Returns a new instance of RecsysNeedsFinder.
6 7 8 |
# File 'app/workers/recsys_needs_finder.rb', line 6 def initialize(user_id) @user = User.find(user_id) end |
Instance Attribute Details
#user ⇒ Object (readonly)
Returns the value of attribute user.
4 5 6 |
# File 'app/workers/recsys_needs_finder.rb', line 4 def user @user end |
Instance Method Details
#call ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'app/workers/recsys_needs_finder.rb', line 10 def call # Get max network_id to use latest recommendations network_id = RecsysResult.distinct.pluck(:network_id).max needs = (list_recommended_needs.sample(1) + latest_needs.sample(1)) needs_scores = get_score scores = needs.map { |need| needs_scores[need.id] || 0.0 } return if needs.empty? begin RecsysMailer.recsys_recommendation(@user, network_id, needs, scores).deliver rescue Postmark::InactiveRecipientError # TODO: Add a flag that user email is wrong somehow and to not send emails again to this user. end # Update has_seen relation (unless needs.empty?) needs.each { |need| @user.add_edge(need, 'has_seen') } end |
#get_score ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'app/workers/recsys_needs_finder.rb', line 75 def get_score # Get scores of recommended needs results = RecsysResult .where(sourceable_node: @user) .where(targetable_node_type: 'Need') .pluck(:targetable_node_id, :value) .uniq Hash[results] end |
#latest_needs ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/workers/recsys_needs_finder.rb', line 30 def latest_needs # # Only select project ids for which the need has not already been seen # # There should not be a RecsysDatum instance for the given user, need and 'has_seen' relation. # has_seen_need_ids = RecsysDatum # .where( # sourceable_node: user, # targetable_node_type: 'Need', # relation_type: 'has_seen') # .pluck(:targetable_node_id) # # Get two latest project needs as default in case the user has no recommendations # # We need to be careful and join with project here because of orphaned Need records # latest_project_ids = Need # .joins(:project) # .where # .not(id: has_seen_need_ids) # .order(id: :desc) # .pluck(:project_id) # .uniq # latest_needs = latest_project_ids.map { |project_id| # Need.where(project_id: project_id).where.not(id: has_seen_need_ids).order(id: :desc) } # ten_latest_needs = latest_needs.flatten.sample(10) Need.last(10).to_a end |
#list_recommended_needs ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'app/workers/recsys_needs_finder.rb', line 64 def list_recommended_needs # Sort recommended needs by decreasing value (needs_ids is ordered this way) # We need to be careful here to avoid orphaned needs # Furthermore, some recommended needs don't concern projects # TODO: handle other types of needs Need .where(id: needs_ids) .to_a # .sort_by { |need| needs_ids.find_index(need.id) } end |
#needs_ids ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'app/workers/recsys_needs_finder.rb', line 54 def needs_ids # Get list of recommended needs and send email @needs_ids ||= RecsysResult .where(sourceable_node: @user) .where(targetable_node_type: 'Need') .order(value: :desc) .pluck(:targetable_node_id) .uniq end |