My last several weeks have been spent diving deep into the Rails framework. From understanding the basics, to creating an entire IoT application, known as AutoMaid. While I believe fully understanding rails and the beauty of her frameworks can take months, if not years, I would consider this a start.
Throughout the making of my application I ran into an array of errors. Steering from Sinatra to Rails was a draw dropper, but even with all the cool gadgets, methods, and simplicity of it, I still felt a little limited. After coming out of Sinatra syntax, I was at first struggling to incorporate some of my previous tricks into my current application. However, after some diligent reading and research into Ruby docs and other blog posts, rails started to release the magic everyone talks about.
One thing I took away from the my upgraded Ruby experience was Rails form helpers. Unlike the long winded and repetitional forms in Sinatra, Rails allows us to use a bunch of methods that make your life 10x easier, and your application 10x better!
For Automaid, I wanted the user to have a pleasant experience. I decided that when creating a new home automation, the user should be able to have a dropdown menu for time selection, as well as device location (room) selection. In this case, the room drop down menu should only include rooms that particular user created. Initially, at the thought of all of this, I was stumped. But after some googling, api docs, and stack overflow...Voila! Dropdown menus exist, all thanks to collection_select.
When looking at the API docs for the first time, it may seem a little confusing. But let's look at what they're asking for!
Here, ":post", refers to the instance of what is being selected, in this case the user is selecting authors to be associated with that specific post. Next, ":author_id", is the params, since the author's ID is what will be associated with the post in the params. "Author.all", is where you would be selecting "author_id" from. So if you were selecting something like category_id, your next argument would be something similar to Category.all. ":id", is specified to obtain the author.id from the Author collection (Author.all). Next, ":name_with_initial", is what your drop down menu items will be shown as. So, back to the Categories example, if Categories had an attribute of "name", you would use the symbol ":name" instead. And finally, "prompt: true", a boolean value that simply means a selection must be made, and it cannot return nil. However, it can also be given a string to define another than the standard prompt ‘Please select’, such as 'Please select a category'.
Now, that wasn't so bad was it?
Understanding collection_select and implementing it into your project can transform a user's form filling experience. But this only covers how to implement it with already made collections, and there are many more ways to use it.
When creating Automaid, I first made my automations "if_action" a string. So the "if-action" would be what triggered the device's automation, and a "then_action" would occur. In a real life situation, that "if_action" would be a time, (i.e. if it is 8:00 p.m., then turn off the light). And given I was already deep into my project (because, yes, there is a time_select), and unsure how to do this, so I ran into an issue. How could I create a collection_select when I didn't technically have collection to select from? Well...make one!
I began by creating a times array that simply consisted of times, as strings, I wanted my user to be able to select from. Because I wasn't sure the extent of where I would need this in my application in the future, I decided to create a method inside my ApplicationHelper, and named it time_options.
By creating this, I can call it as a collection in my automation form.
Since collection_select still needs the other arguments, instead of referring to the id and what is being displayed (since I am pulling from an array of strings), I used "to_s" (to string), since that is the argument that I am expecting to receive, as well as what I want displayed. If you were to use an array of integers, this would be "to_i". You get the point!(hopefully...)
Here are the wonderful results yielded by this collection_select:
After some questions, coffee breaks, and hair pulling, a convenient drop down menu exists. 😎
Collection_select offers a variety of methods to utilize, and if it doesn't fit what you need, there are many other select methods that will.