a SOLID hurdle

solid ruby rails fast tests

![Mountains surrounded by clouds](https://images.unsplash.com/uploads/14128434147336bfb286b/e76494ac?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=900&fit=max&s=0d14ef0b6c5eeee1561a0e340d48ae41)<br> [Photo by Aleksandra Boguslawska](https://unsplash.com/aleksandraboguslawska) I first heard of the [SOLID priciples](https://www.youtube.com/watch?v=WpkDN78P884) from Gilbert, my MakerSquare teacher. A brilliant idea emerged of how to pull domain logic outside of dependencies ( i.e. Rails ). The idea is to treat Rails as a mechanism to delivery content. All domain logic can live outside of Rails as a PORO ( Plain Old Ruby Object). There is always one hurdle I keep bumping into. > How do you query the database without using Active Record? I've read several approaches on how to make an in memory repository ( a wrapper around a hash ). ```ruby class Domain class InMemory class << self def persist(data) @store[increment_id] = data end def increment_id @id += 1 end end end end ``` Which works awesome if your app only consists of one model. More often than not domain logic will have multiple models working together to paint a bigger picture. To build in memory objects that mimic this behavior sounds awful close to rebuilding an ORM over ruby hashes. I honestly think that's overkill. The main benefits of the SOLID principles are to speed up tests and reduce coupling. Which I'm all in favor for. It's like asking who's a fan of being happier!? I have been bouncing around a couple ideas of how to separate the power of AR querying provides into a PORO. But they're really rough drafts. So instead I rather share with you what works. <br> At Spredfast we have a big o Rails app. Big o Rails means slow tests. I recently had to build an endpoint to validate some json and create models from it. The steps were 1) validate json 2 ) create models. Don't need Rails in one of the two steps. So what do I do? I make a class to validate what I am expecting in the json and throw errors if the json has missing properties. The class looks something like this: ```ruby class Validator def initialize(raw_json) @raw_json end def validate! convert_json_into_hash! ensure_valid_spec_fields! @spec end def convert_json_into_hash! @spec = MultiJson.parse(@raw_json) rescue MultiJson::ParseError => e raise_error("You have passed in invalid JSON: #{e.message}") end def ensure_valid_spec_fields! raise_error("Spec must have a templates property") unless @spec["templates"] end end ``` Yes I am forcing Ruby to behave like Java. There is one dependency in this class. `MultiJson` which is perfectly fine. In my test suite, I can require the gem by itself. I don't have to load up a Rails environment or any other gem we used in our monorail, believe me we have tons. This is how I use it in Rails: ```ruby class SomeController < ApplicationController def create spec = Validator.new(params[:spec]).validate! template = Template.create_from_spec(spec) render :json => { template: template }, :status => 200 rescue Validator::Error => e render :json => { error: e.message}, :status => 406 end end ``` I'm beginning to explore where this technique is applicable and where it isn't. Right now it is unclear to me how far one can go with this. Trust me that I'll keep pushing the boundaries to see where it will go.

When to use Private

ruby testing tdd

![Blurred out freeway](https://images.unsplash.com/uploads/1413259835094dcdeb9d3/6e609595?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=900&fit=max&s=2d48b463e834118ff7a20cb54256db45) [Photo by: Israel Sundseth](https://unsplash.com/kappuru) Private methods in ruby were explained to me as methods you don't need / want to test. This was super unclear to me. It became more clear as I started writing more tests. I shall dispense of my experience in the following...ready set go! Say we're working on a class retrieves car models from Edmund's API. Our class API would work something like: ```ruby CarModels.new({year: "2015", manufacture: "Subaru"}).get_list ``` There are a few steps we have to do to get this list. First we have to make a request with the proper params to a url, translate the response from a string to JSON, and then we have to iterate through the data to collect the models. The client ( person / object ) who is using this class **doesn't care** how the class gets the information. The only things the client cares about is the list. In fact I don't even care where the class gets the information I just want to see an array of models Subaru has available in 2015. >The client ( person / object ) who is using this class **doesn't care** how the class gets the information. Inside the CarModels class we'll have to define `#get_list` and have it do all the steps I previously babbled about. It might look something like: ```ruby def get_list get_raw_info_from_api translate_raw_response collect_car_models end ``` In TDD we would now write tests to make sure every one of these "step methods" work the way we want them to. `#get_raw_info_from_api` makes a request with the correct parameters and hits the correct endpoint and assigns `@response` to the response it received and yaddity ya ya. At the end of the cycle you will have a whole bunch of tests and a class you cannot refactor without breaking things. For example if I wanted to rename `#get_raw_info_from_api` to `#get_info_from_store` my test would break because my method got renamed. Or lets say the endpoint of the method changed, or we decided to check for a cached version first before making the api call. Or instead we use pixie dust. Or we face the fact that software always changes and we give up on TDD!!! > Don't give up on TDD!!! Instead delete all the tests for the step methods and leave the test for `#get_list`. Don't allow your tests to be so nosey that it prevents you from easily refactoring your class. This is where private comes in. The only method the client cares about is `#get_list` all other methods should be private because a client will never use `#collect_car_models` on it's own. The client would need to call `#translate_raw_response` which will then need to call etc etc. A client will never care about the steps you take to get the list. But WHY?!?! break up all those steps into private methods if they are never used by the client!?!?! Well guess you'll have to wait for the next post. =)

Now or never

![The journey begins](https://images.unsplash.com/42/QrXgXMhCSouyhU7idq7g_IMG_8402.JPG?crop=entropy&fit=crop&fm=jpg&ixjsv=2.1.0&ixlib=rb-0.3.5&q=80&w=900)<br> [Photo by Kelley Bozarth](https://unsplash.com/kelleybdeal) I've been wanting to move my blog from Wordpress to Rails ever since I graduated from MakerSquare ( Nov 9th, 2013 ). I made up countless excuses not to. See I'm a bit of a perfectionist. I wanted my blog to be perfect. The right colors, cool ui animations, photographs so on and so forth. But I would have nothing to show for it. So....here we are. At the beginning rough, dirty and not perfect. It's not enough to have an idea, you have to take action. So here goes nothing! > It's not enough to have an idea, you have to take action. I promise I will iterate on this blog to make it more pleasant.