Ruby Console Underscore Shortcut

Nifty shortcut in the ruby console here

How to Override and Customize the Devise Controller in Rails

Judging by the number of different StackOverflow questions, there are a lot of people trying to do this, and a lot of confusion. Here is how I did it, and hopefully it helps you.

I have a User and a Verifier model.  What I want to do is create a new Verifier every time I create a new user, and pass in the user.id for the User into the verifier.user_id so that they are mapped together.

In order to do this I want to not really override but add additional functionality to the existing devise controller that handles when new users are created (and destroyed).  So I need to access the RegistrationsController#Create function in devise.

First thing is to create a new folder in the ‘app/controllers‘ folder where we can put my custom controller.  I called mine ‘app/controllers/my_devise‘.  Then create a new file in this folder called registrations_controller.rb

Screen Shot 2013-12-27 at 1.24.38 PM

It is called ‘registrations_controller‘ because that is what devise calls its controller that handles new user sign ups.  We want it to inherit from the original devise controller:

Screen Shot 2013-12-27 at 1.27.23 PM

Ok, so since I want to create some custom logic that happens when a new user is created, I want to override and customize the ‘create’ function:

Screen Shot 2013-12-27 at 1.36.31 PM

So you’ll notice the ‘super’ command is called at the beginning.  This is because I want to keep the original functionality of the devise create function, and just add my own additional logic.  If you want to completely customize and override the devise create function, then you don’t want this line.

Now at fist I was tempted to use ‘if user.save’, because I want to create a new Verifier when a User is created, however the devise registrations controller uses ‘resource’, so thats what I want to access here.  In my case, the model that I use with devise is User, so in my case ‘resource’ means ‘user’.  Yours will depend on how you set up devise at the beginning.

Now importantly don’t forget to also delete the linked Verifier when the User is deleted.  I used the same idea to override and customize the destroy function:

Screen Shot 2013-12-27 at 1.39.28 PM

Some things to note here.  I  used the find_all_by_user_id function to get all the Verifiers that are linked to the User that we are destroying in this function.  Since each User only has one Verifier,  I could have used find_by_user_id.  I decided to use find_all_by_user_id, just in case something weird happened and two Verifiers were linked to one User.  This would ensure they all get deleted.  Now note that find_all_by_user_id returns an array of values, even if the array only has a single element.  So thats why I need to use the each function to iterate through the array, even if it only has a single element.  This is because the destroy function cannot be called on an array, but only on a single instance.

So now when I create a new User, a Verifier is also created whose user_id value matches the User.id value.

Two things remain to do.  First, we need to copy the ‘views/devise/registrations‘ files into a custom folder that matches the custom folder we made for our registrations_controller.rb.  So I copied mine into ‘views/my_devise/registrations

Screen Shot 2013-12-27 at 1.54.47 PM

Lastly we need to update the config/routes.rb file to point to our custom controller

Screen Shot 2013-12-27 at 1.56.45 PM

If you get a routing error, try using { :registrations => "my_devise/registrations" } I got an error in production when running on heroku, and using this route worked.

That’s it!

Now I’ve been thinking that there might be a better way to do this linking a Verifier with a User with rails associations, so if you know of one, please let me know!

Here is a link to the devise registrations_controller.rb so you can see the default functions.  The devise documentation is also helpful, and I want to give credit to these StackOverflow questions which also helped me a lot. (one, two, three)

Want to learn more about Ruby on Rails?  Checkout OneMonthRails, what I used to get started in Rails. Best Rails course I’ve ever seen!

Fixing Bootstrap Navbar Covering Content

If you use Twitter Bootstrap for your rails app, you may have come across the issue where the navbar covers part of the content of your page.

Screen Shot 2013-12-21 at 10.37.41 AM

 

There is an easy fix.  Add some padding to your the body in CSS.

styles.css.scss

Screen Shot 2013-12-21 at 10.39.07 AM

Rails Naming Conventions

Short and sweet:

Scaffolds and Models are singular, controllers are plural.

rails g model User

rails g controller Users

rails g scaffold User

Rails 4 Form Dropdown Menu with collection_select

Perhaps this was simple for you, but as someone still learning rails, I found confusing and conflicting examples and explanations on how to use collection_select in a rails form, especially with a has_many through association using accepts_nested_attributes_for.  It took me several hours to finally get it working.  Hopefully this will save you some time.

So I have a PurchaseOrder model that is linked to the Items model via a has_many through association, with the join model called Quantities, as you can see below.

purchase_order.rb

Screen Shot 2013-12-18 at 5.15.51 AM

quantity.rb

Screen Shot 2013-12-18 at 5.17.28 AM

item.rb

Screen Shot 2013-12-18 at 5.18.30 AM

And I have a form with nested fields using accepts_nested_attributes_for that looks like this:

purchase_orders/_form.html.erb

Screen Shot 2013-12-18 at 5.21.34 AM

which looks like this in the browser:

Screen Shot 2013-12-18 at 5.23.45 AM

and here’s the _quantity_fields.html.erb partial:

Screen Shot 2013-12-18 at 5.26.10 AM

So here is how I got the dropdown menu for “Part Number” using collection_select.

What I had trouble with was what variables to pass into the collection_select function.  They go as follows:

collection_select ‘model field’, ‘collection of options in the dropdown menu’, ‘model field for values’, ‘model field to show in the menu’

You’ll notice the @items that I passed in to the collection_select.  I created this in the PurchaseOrders controller in the new, create, edit, and update functions:

@items = Item.all.order("part_number")

I read the official rails documentation for collection_select, but it still left me a bit confused.   I also found help from two StackOverflow questions (one, two) that I want to give credit to, and may help you as well.

Let me know if this helped you!

Overriding Bootstrap and Bootstrap Sass in Rails

So many of you who use rails know that bootstrap is an extremely popular CSS and Javascript add-on used by many rails developers.  I use the Bootstrap-Sass gem by Thomas McDonald.

Today I wanted to override the bootstrap css in my app to make the ‘container’ class 100% width with no margin.  I want to save you some time that I spent searching around.

I found these two posts on the ever useful Stack Overflow, but since I used a gem instead of the ‘require’ to add bootstrap to my app, this didn’t work for me.  So here is what worked.  

Basically you just need to make sure that whatever custom css or overriding css you are using is loaded after bootstrap.  So I simply moved my custom “.container” class after the “@import bootstrap” lines in my styles.css.scss file:

Screen Shot 2013-12-14 at 7.00.16 PM

I guess it might not be the most efficient way to load one css file then load a second to override it, but I don’t know how to do it any other way…..yet 🙂

Let me know if this helped you!

The difference between link_to and mail_to in Ruby on Rails

Small difference, but important.  They are essentially reversed.  Since jonathan ng said it better than me, and I found this resource from his blog, I’m going to credit and link to his post from his Ruby on Rails blog:

Screen Shot 2013-12-04 at 9.23.08 PM