Created
March 12, 2014 16:45
-
-
Save jrunning/9511047 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class College < ActiveRecord::Base | |
| scope :ranked_at_least, ->(rank_low=nil) { | |
| # If no value is given just return self without adding any conditions | |
| if rank.nil? then self | |
| else where("us_news_ranking <= ?", rank_low) | |
| end | |
| } | |
| scope :with_sat_composite { | |
| # Using an array for select() instead of a string means we can can chain | |
| # selects and fields won't be duplicated | |
| select([ | |
| "*", | |
| "(colleges.sat_math_25 + colleges.sat_math_75 + "\ | |
| "colleges.sat_reading_25 + colleges.sat_reading_75) / 2 "\ | |
| "AS sat_composite" | |
| ]) | |
| } | |
| scope :with_sat_composite_at_least, ->(sat_low=nil) { | |
| if sat_low.nil? then self | |
| else | |
| # Use the `with_sat_composite` scope above to use the `sat_composite` | |
| # field in our query | |
| with_sat_composite.where("sat_composite >= ?", sat_low) | |
| end | |
| } | |
| scope :with_sat_composite_at_most, ->(sat_high=nil) { | |
| if sat_high.nil? then self | |
| else with_sat_composite.where("sat_composite <= ?", sat_high) | |
| end | |
| } | |
| scope :with_act_composite { | |
| select([ | |
| "*", | |
| "(colleges.act_composite_25 + colleges.act_composite_75) / 2 "\ | |
| "AS act_composite" | |
| ]) | |
| } | |
| scope :with_act_composite_at_least, ->(act_low=nil) { | |
| if act_low.nil? then self | |
| else with_act_composite.where("act_composite >= ?", act_low) | |
| end | |
| } | |
| scope :with_act_composite_at_most, ->(act_high=nil) { | |
| if act_high.nil? then self | |
| else with_act_composite.where("act_composite <= ?", act_high) | |
| end | |
| } | |
| scope :with_tuition_for_state, ->(state_name=nil) { | |
| # If no state is given, default to `out_of_state_tuition` | |
| if state_name.nil? | |
| "out_of_state_tuition AS tuition_for_state" | |
| else | |
| # Make sure we sanitize any value given by the user | |
| tuition_for_state_sql = <<-ENDSQL | |
| CASE WHEN colleges.state = #{ ActiveRecord::Base.sanitize state_name } | |
| THEN in_state_tuition | |
| ELSE out_of_state_tuition | |
| END AS tuition_for_state | |
| ENDSQL | |
| select([ "*", tuition_for_state_sql ]) | |
| end | |
| } | |
| scope :with_total_cost_for_state, ->(state_name=nil) { | |
| # Use the `with_tuition_for_state` scope from above to use the | |
| # `tuition_for_state` field in our query | |
| with_tuition_for_state(state_name) | |
| # Calculate total cost and put it in a field named `total_cost_for_state` | |
| .select([ "*", "tuition_for_state + room_and_board AS total_cost_for_state" ]) | |
| } | |
| scope :with_total_cost_for_state_at_least, ->(state_name=nil, cost_low=nil) { | |
| if cost_low.nil? then self | |
| else | |
| with_total_cost_for_state(state_name) | |
| .where("total_cost_for_state >= ?", cost_low) | |
| end | |
| } | |
| scope :with_total_cost_for_state_at_least, ->(state_name=nil, cost_high=nil) { | |
| if cost_high.nil? then self | |
| else | |
| with_total_cost_for_state(state_name) | |
| .where("total_cost_for_state <= ?", cost_high) | |
| end | |
| } | |
| # Use an options hash so you don't have to remember what order you have to | |
| # put the arguments in | |
| def self.get_college(opts) | |
| self.where( { category: opts[:type] } if opts[:type].present? ) | |
| # Since all of our scopes are set up to handle nil (and falsy) values we | |
| # don't have to do any `if`s here and we can just chain the scopes one | |
| # after the other | |
| .ranked_at_least( opts[:rank_low] ) | |
| .with_sat_composite_at_least( opts[:sat_low] ) | |
| .with_sat_composite_at_most( opts[:sat_high] ) | |
| .with_act_composite_at_least( opts[:act_low] ) | |
| .with_act_composite_at_most( opts[:act_high] ) | |
| .with_total_cost_for_state_at_least( opts[:in_state], opts[:cost_low] ) | |
| .with_total_cost_for_state_at_most( opts[:in_state], opts[:cost_high] ) | |
| end | |
| end | |
| # Usage: | |
| # With the options hash it's a lot more readable here, too | |
| College.get_college( type: "national", | |
| rank_low: 10, | |
| sat_low: 1300, | |
| in_state: "New York", | |
| cost_high: 60_000 ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment