It has been fourteen weeks since I embarked on my journey to becoming a Software Engineer with Flatiron School. Armed with the knowledge I’ve gained, I was ready to face my biggest opponent yet, Ruby on Rails. I was apprehensive, but eager to face this beast. Now that I am on the other side of this project, I am grateful for the challenge it gave me.
I’ve created Doc on Dec. An app that allows you search by state or specialty, to find a doctor near you that meets your needs. Once you find a doctor that meets your criteria, you are able to book an appointment with them. From there you can reschedule, cancel, or make more appointments within the app. You can try it out for yourself here. (Please note that I’ve included seeded data in order for you to get a better understanding of how the app functions.) While building this app, I ran into several issues, that forced me to slow down and gain a better understanding of the concepts. The concept that gave me the most hassle, scope.
Well what the heck is scope anyhow?
Scopes are custom queries defined in your Rails models that you define using the scope method. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL. These scope methods can be chained on to any block of code, given they are of the same class. Scope takes in two different arguments, a name and lambda. A name is self explanatory, without one we wouldn’t be able to call it anywhere. Lambda functions are small but mighty. Identified with their “->”, they allow us to execute inline logic.
I have written three separate scopes for my Doctor model. The first scope, :search_by_state_and_specialty is a search feature. I used SQL to establish the parameters of the search. (More on this below.) The second, :list_of_specialties, uses .distinct to specify that the doctor’s specialty record will be unique. Lastly, :alphabetical_order orders the doctors by their state in alphabetical order.
Calling scope results in a
ActiveRecord::Relation scope object, which means that it is “chainable”. Within my DoctorsController, my #index method, utilizes this “chainable” feature in every instance of the conditional statement.
Lines 5–6 is passing in the variables [:query] and [:specialty] that the user has input to the search feature. Line 8, will display all of the doctors by state, in alphabetical order.
When should we use scope?
We use scope methods when we do not want to recall the same class method code in your controller or class. Imagine having to hunt down each time the method is called and make revisions. We aim to work smarter, not harder. Scope should be utilized when you feel yourself calling to the same class method repetitively.
Why should we use scope?
Scope will create some beautiful syntax “sugar” we, as developers, strive for. Scopes can (and love to) return other scopes. This is most useful when methods return the same kind of object. After all, they are the easiest to debug if the code needing edits, is all in one place.
Scope was mind bending when I first learned the concept. However, I now feel like they are going to be a frequently-reached-for tool in my Rails toolbox.