Rails: Remove a table

I created a table that I did not need. I needed to remove the table. The actual terminology is to Drop a table. The way you do this is to create a new migration.

rails g migration DropProducts

In my case, I created a products table when I didn’t needed it. Inside the migration, I do the following.

class DropProducts < ActiveRecord::Migration
  def change
    drop_table :products
  end
end

fin

Railscast – 002 Dynamic find_by Method

The GitHub Repo

I was arguing if this episode was even worth creating a project for. Decided to create since it would be so quick to make.

The episode talks about how you can replace:

class TaskController < ApplicationController
  def incomplete
    @tasks = Task.find(:all, :conditions => ['complete = ?', false])
  end

  def last_incomplete 
    @task = Task.find(:first, :conditions => ['complete =?', false], :order => 'created_at DESC')
  end
end

With:

class TaskController < ApplicationController
  def incomplete
    @tasks = Task.find_all_by_complete(false)
  end

  def last_incomplete
    @task = Task.find_by_complete(false, :order => 'created_at DESC')
  end
end

Attention should be drawn to the find_all_by_complete method used. This is a shortcut for the first find methods with all of the options passed in. The word that follows the by is the column that is in the Tasks table. You can then pass in the value of the records for that column you want returned. If you want only a single record that matched the conditions, then you would omit the all from find_all_by_complete making it find_by_complete. If you were finding a record by its name, then you doing this:

Task.find_by_name('bob')

Railscast – 016-Virtual-Attributes

The GitHub Repo
The Heroku app

I found this episode useful. It showed me that a model’s attribute does not have to be directly on one of the table’s columns. Not only did I learn about virtual attributes, but I also improved on associations, validations, and callbacks.

The virtual attributes were easy enough to understand. You create a setter and getter method named with the desired virtual attribute name. In the episode’s case it was price_in_cents sort of aliased to price_in_dollars. Within the method you could change the value of the virtual attribute to match whatever is in the database.

def price_in_dollars
  price_in_cents.to_d / 100 if price_in_cents
end

def price_in_dollars=(dollars)
  self.price_in_cents = dollars.to_d * 100 if dollars.present?
end 

Strftime

This is the first time I used the :strftime method, but it is not too dissimilar to how I have formatted dates within the terminal.

Rails 3 to Rails 4

One thing to note, these videos date back sometime before the current Ruby on Rails 4.0 release, thus I must convert some of the techniques shown in the videos into whatever they translate to in the new version of the framework. An example of this is the use of attr_accessible. Attr_accessible has been incorporated in the the strong parameters update in Rails 4. So instead of

attr_accessible :name, :price_in_dollars, :released_at_text, :category_id, :new_category, :tag_names

You would do the following in the ProductsController

def product_params
  params.require(:product).permit(:name, :price_in_dollars, :released_at_text, :category_id, :new_category, :tag_names)
end

Associations

I knew I was a little weak with associations, so when I saw that this project had categories, products, tags, and taggings, I decided to make everything from scratch. I followed along with the schema to create the migrations needed. When creating a has_many and belongs_to relationship you always put the parent id onto the child’s table. Example:

class Product < ActiveRecord::Base
  belongs_to :category
end

class Category < ActiveRecord::Base
  has_many :products
end

The schema would look like this:

 create_table "categories", :force => true do |t|
    t.string   "name"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "products", :force => true do |t|
    t.string   "name"
    t.integer  "category_id"
    t.datetime "created_at",     :null => false
    t.datetime "updated_at",     :null => false
  end

This relationship is similar to the taggings, tags, and products relationship. The taggings has the foreign key for both the tags and products. The difference is that products has_many tags through the taggings model.

Validations

I liked how Ryan Bates created his own custom validation method with check_released_at_text The validation first check if the released_at_text instance variable is present and the time is nil. If it is, then add to the errors object with a custom error message. If there was an ArgumentError, then again the errors object is appended with the custom error message. Creating a custom validation adds more control than if some of the more generic validation methods like presence or length.

Callbacks

The callbacks created this episode used before_save. The reasoning for this is to actually save the instance variable’s values to the database in the correctly formatted form. In the create_category callback it actually creates a new category record.

  def create_category
    self.category = Category.create!(name: new_category) if new_category.present?
  end

Pluck

The first time I’ve seen the pluck method used. I looked it up and found that tags.pluck(:name) is a shortcut for tags.map(&:name). The goal is to get only a certain attribute from the model.

Those where the noteworthy parts of the episode.

Make all Railscast Projects

I came across a post about someone asking what was the best way to learn Ruby on Rails via Quora. One answer suggested one of the best ways was to follow along with every Railscast project then upload the repo to both GitHub and Heroku. I liked the concept, so I have bought a membership of Railscast and have downloaded all the episodes.

While the goal is to create every project, I will watch every episode and decide if it would be useful to make the project or not. Some episodes are just small tips, so creating a new project just to use that one tip seems inefficient.

I might be repeating what episodes showed, but I found that writing about what I learnt from the episode solidifies what I have learnt. Similar to language learning, you need a balance of input and output to get good at any skill. The input here are the Railscast episodes and the things I look up to finish the apps, and the output are the working app and the blog post.

The first few days of trying this method, I created an app then wrote up the blog post. This takes a lot of context switching between tasks. I am currently trying to go through as many Railscasts in one day, then writing about each the following day.

My First Ruby Gem: body_id

I created my first Ruby Gem: body_id on GitHub, and I have successfully implemented it my own project. My goals were to see what goes in making a gem and making a process simpler.

The Problem
I first saw the use of @bodyid when Derek Sivers announced that he open sourced all his projects. Which was useful in learning about Sinatra He had @bodyid in his controller, and he called it within the body tag.

When I saw this, I thought it was incredibly useful for styling, so I used it on my own rails project. The problem arose when I was defining my @bodyid to strings like page-index or new-car. Eventually each controller action had a @bodyid.

The Solution
I searched online if anyone already made a gem that did this, and I found these two links. Automatic Body ID in Rails on GitHub and Create a simple Rails 3 text helper Gem by on StackOverflow. The first link showed how you could combine the controller and action name into a single string. I like how he extracted my current process out into a helper, but I saw there were a few unnecessary method calls.

The second link essentially asked how to make the same gem I was planning on making. What I liked about his approach was how he made the id both semantic and similar to RESTful Rails path name. i.e. new_page_path and new_page_view. The answers and the asker’s GitHub repo was key to showing me how to make the actual gem.

There was a problem with these two helpers however. They both did not allow for the user to define their own ID in case they wanted  to diverge from the helper’s convention. That’s where I added a simple || operator with the generated ID and an instance variable defined within the controller.

The final helper:

    def body_id
      controller = controller_name.singularize.underscore
      action = action_name.underscore
      body_id = “#{ controller }-#{ action }”.gsub(/_/, ‘-‘)
      # Controller declared instance variable
      # or helper generated string
      @body_id || body_id
    end

I first removed the controller object in favor to just calling controller_name and action_name directly. This eliminates the need for the gsub() to make ‘controller’ to nothing. Next was the underscore(). I wasn’t sure why I needed this method until I remembered that some controller names and action names were written in CamelCase, so if I wanted to have the generated output look more consistent, then it would be best to leave it in. Finally I combined the two variables into the body_id variable after replacing _underscore with – hyphens to match with CSS conventions. The last line determines if we’ll use the controller declared instance if truthy or the helper’s generated string if @body_id is not defined.

I used bundler to generate the gem files I needed, while I referenced RailsCast #245 New Gem with Bundler and Railtie’s docs One of the things I read online about making a gem was to add some graphics love and make good README. So I got some Illustrator practice in while making the gem’s logo, and I looked at other README for common practices.

Overall I found the process easier than I thought it would be and helpful in understanding what goes into making a simple open source Ruby Gem available.

Fork me on GitHub the4dpatrick / body-id-gem