diff --git a/app/controllers/phenotypes_controller.rb b/app/controllers/phenotypes_controller.rb index 41e819e..69b05c0 100644 --- a/app/controllers/phenotypes_controller.rb +++ b/app/controllers/phenotypes_controller.rb @@ -83,81 +83,32 @@ class PhenotypesController < ApplicationController end def show - @phenotype = Phenotype.find(params[:id]) || not_found - @comments = PhenotypeComment - .where(phenotype_id: params[:id]) - .order('created_at ASC') + @phenotype = Phenotype.find(params[:id]) + @comments = @phenotype + .phenotype_comments + .order('created_at ASC') @phenotype_comment = PhenotypeComment.new @user_phenotype = UserPhenotype.new - - recommender = PhenotypeRecommender.new - similar_ids = recommender.for(params[:id]) - # For some reason, Recommendify sometimes returns items of class Integer, - # sometimes of class Recommendify. - if similar_ids[0].is_a?(Recommendify::Neighbor) - similar_ids = similar_ids.map(&:item_id) - end - @similar_phenotypes = Phenotype - .where('id in (?)', similar_ids) - .limit(6) + @similar_phenotypes = + PhenotypeRecommender.new.recommendations_for(@phenotype.id, 6) end def recommend_phenotype - # init the recommendation-engines - @phenotype_recommender = PhenotypeRecommender.new - @variation_recommender = VariationRecommender.new + @phenotype = Phenotype.find(params[:id]) # get up to three similar phenotypes regardless of variation - - @similar_ids = @phenotype_recommender.for(params[:id]) - @similar_phenotypes = [] - @item_counter = 0 - - @similar_ids.each do |s| - if @item_counter < 3 - @phenotype = Phenotype.find(s.item_id) - if current_user.phenotypes.include?(@phenotype) == false - @similar_phenotypes << @phenotype - @item_counter += 1 - end - else - break - end - end + @similar_phenotypes = + PhenotypeRecommender.new.recommendations_for(@phenotype.id, 3) # get up to three similar combinations of phenotype and variation - @user_phenotype = UserPhenotype.find_by_phenotype_id_and_user_id(params[:id],current_user.id) - if @user_phenotype != nil - @users_variation = @user_phenotype.variation - @variation_recommend_request = params[:id] + '=>' + @users_variation - else - @variation_recommend_request = '' - end + @user_phenotype = @phenotype + .user_phenotypes + .find_by(user_id: current_user.id) + @similar_variations = + VariationRecommender.new.recommendations_for(@user_phenotype, 3) - @similar_combinations = @phenotype_recommender.for(@variation_recommend_request) - @similar_variations = [] - @combination_counter = 0 - - @similar_combinations.each do |s| - if @combination_counter < 3 - @phenotype = Phenotype.find_by(id: s.item_id.split('=>')[0]) - if current_user.phenotypes.include?(@phenotype) == false - @similar_variations << s - @combination_counter += 1 - end - else - break - end - end - - @phenotype = Phenotype.find_by(id: params[:id]) - - if @similar_phenotypes == [] and @similar_variations == [] + if @similar_phenotypes.none? && @similar_variations.none? redirect_to action: 'index' - else - respond_to do |format| - format.html - end end end diff --git a/app/recommenders/phenotype_recommender.rb b/app/recommenders/phenotype_recommender.rb index 28ccb7c..497f4df 100644 --- a/app/recommenders/phenotype_recommender.rb +++ b/app/recommenders/phenotype_recommender.rb @@ -17,4 +17,14 @@ class PhenotypeRecommender < Recommendify::Base process! end + + def recommendations_for(id, count) + phenotype_ids = self.class + .new + .for(id) + .take(count) + .map(&:item_id) + return [] if phenotype_ids.empty? + Phenotype.find(phenotype_ids) + end end diff --git a/app/recommenders/variation_recommender.rb b/app/recommenders/variation_recommender.rb index 27a72a7..b8d46c2 100644 --- a/app/recommenders/variation_recommender.rb +++ b/app/recommenders/variation_recommender.rb @@ -18,4 +18,40 @@ class VariationRecommender < Recommendify::Base process! end + def recommendations_for(user_phenotype, count) + neighbors = self.class + .new + .for("#{user_phenotype.phenotype_id}=>#{user_phenotype.variation}") + .take(count) + phenotype_ids = neighbors.map(&method(:phenotype_id_from_neighbor)) + phenotypes = Phenotype.find(phenotype_ids).index_by(&:id) + + neighbors.map do |neighbor| + phenotype = phenotypes.fetch(phenotype_id_from_neighbor(neighbor)) + Recommendation.new(neighbor, phenotype) + end + end + + private + + def phenotype_id_from_neighbor(neighbor) + neighbor.item_id.split('=>').first.to_i + end + + class Recommendation + attr_reader :phenotype + + def initialize(neighbor, phenotype) + @neighbor = neighbor + @phenotype = phenotype + end + + def variation + neighbor.item_id.split('=>').last + end + + private + + attr_reader :neighbor + end end diff --git a/app/views/phenotypes/recommend_phenotype.html.erb b/app/views/phenotypes/recommend_phenotype.html.erb index d8d1469..d7019f7 100644 --- a/app/views/phenotypes/recommend_phenotype.html.erb +++ b/app/views/phenotypes/recommend_phenotype.html.erb @@ -1,30 +1,61 @@ -<%if @similar_variations != []%> -