Monday, August 22, 2016

PHP print_r Equivalent in rails

In PHP you can print the human-readable information about a variable. In the views, the Rails equivalent is:


<%= debug obj %>
You can also use pretty print 'pp', in IRB:

require 'pp'

pp obj

In Rails console, you don't have to require 'pp'. The print method is used to inspect a variable. It will call the to_s method of an object. Doing:

print obj

is equivalent to:

obj.to_s




Example:
class Demo
  def to_s
    "This is a demo"
  end
end

d = Demo.new

print d
This will print: "This is demo"








Thursday, August 18, 2016

rails generate model

Usage:
  rails generate model NAME [field[:type][:index] field[:type][:index]] [options]

Options:
      [--skip-namespace], [--no-skip-namespace]  # Skip namespace (affects only isolated applications)
      [--force-plural], [--no-force-plural]      # Forces the use of the given model name
  -o, --orm=NAME                                 # ORM to be invoked
                                                 # Default: active_record

ActiveRecord options:
      [--migration], [--no-migration]        # Indicates when to generate migration
                                             # Default: true
      [--timestamps], [--no-timestamps]      # Indicates when to generate timestamps
                                             # Default: true
      [--parent=PARENT]                      # The parent class for the generated model
      [--indexes], [--no-indexes]            # Add indexes for references and belongs_to columns
                                             # Default: true
      [--primary-key-type=PRIMARY_KEY_TYPE]  # The type for primary key
  -t, [--test-framework=NAME]                # Test framework to be invoked
                                             # Default: test_unit

TestUnit options:
      [--fixture], [--no-fixture]   # Indicates when to generate fixture
                                    # Default: true
  -r, [--fixture-replacement=NAME]  # Fixture replacement to be invoked

Runtime options:
  -f, [--force]                    # Overwrite files that already exist
  -p, [--pretend], [--no-pretend]  # Run but do not make any changes
  -q, [--quiet], [--no-quiet]      # Suppress status output
  -s, [--skip], [--no-skip]        # Skip files that already exist

Description:
    Stubs out a new model. Pass the model name, either CamelCased or
    under_scored, and an optional list of attribute pairs as arguments.

    Attribute pairs are field:type arguments specifying the
    model's attributes. Timestamps are added by default, so you don't have to
    specify them by hand as 'created_at:datetime updated_at:datetime'.

    As a special case, specifying 'password:digest' will generate a
    password_digest field of string type, and configure your generated model and
    tests for use with Active Model has_secure_password (assuming the default ORM
    and test framework are being used).

    You don't have to think up every attribute up front, but it helps to
    sketch out a few so you can start working with the model immediately.

    This generator invokes your configured ORM and test framework, which
    defaults to Active Record and TestUnit.

    Finally, if --parent option is given, it's used as superclass of the
    created model. This allows you create Single Table Inheritance models.

    If you pass a namespaced model name (e.g. admin/account or Admin::Account)
    then the generator will create a module with a table_name_prefix method
    to prefix the model's table name with the module name (e.g. admin_accounts)

Available field types:

    Just after the field name you can specify a type like text or boolean.
    It will generate the column with the associated SQL type. For instance:

        `rails generate model post title:string body:text`

    will generate a title column with a varchar type and a body column with a text
    type. If no type is specified the string type will be used by default.
    You can use the following types:

        integer
        primary_key
        decimal
        float
        boolean
        binary
        string
        text
        date
        time
        datetime

    You can also consider `references` as a kind of type. For instance, if you run:

        `rails generate model photo title:string album:references`

    It will generate an `album_id` column. You should generate these kinds of fields when
    you will use a `belongs_to` association, for instance. `references` also supports
    polymorphism, you can enable polymorphism like this:

        `rails generate model product supplier:references{polymorphic}`

    For integer, string, text and binary fields, an integer in curly braces will
    be set as the limit:

        `rails generate model user pseudo:string{30}`

    For decimal, two integers separated by a comma in curly braces will be used
    for precision and scale:

        `rails generate model product 'price:decimal{10,2}'`

    You can add a `:uniq` or `:index` suffix for unique or standard indexes
    respectively:

        `rails generate model user pseudo:string:uniq`
        `rails generate model user pseudo:string:index`

    You can combine any single curly brace option with the index options:

        `rails generate model user username:string{30}:uniq`
        `rails generate model product supplier:references{polymorphic}:index`

    If you require a `password_digest` string column for use with
    has_secure_password, you can specify `password:digest`:

        `rails generate model user password:digest`

    If you require a `token` string column for use with
    has_secure_token, you can specify `auth_token:token`:

        `rails generate model user auth_token:token`


Here is the examples for using model generator in Rails 5:

    `rails generate model account`

        For Active Record and TestUnit it creates:

            Model:      app/models/account.rb
            Test:       test/models/account_test.rb
            Fixtures:   test/fixtures/accounts.yml
            Migration:  db/migrate/XXX_create_accounts.rb

    `rails generate model post title:string body:text published:boolean`

        Creates a Post model with a string title, text body, and published flag.

    `rails generate model admin/account`

        For Active Record and TestUnit it creates:

            Module:     app/models/admin.rb
            Model:      app/models/admin/account.rb
            Test:       test/models/admin/account_test.rb
            Fixtures:   test/fixtures/admin/accounts.yml
            Migration:  db/migrate/XXX_create_admin_accounts.rb

Manifest File

A manifest file contains metadata for a group of files that are part of a coherent unit. In Rails, app/assets/javascripts/application.js is a manifest file. In this case the metadata is the directives that include javascript libraries.

//= require jquery
//= require jquery_ujs
//= require_tree .

Monday, August 15, 2016

The Yo Yo Problem in Rails Source Code

This problem is prevalent in Rails framework. The super is used a lot that makes understanding the large framework code base difficult. You have to look up the hierarchy and consider the inherited behavior and state from the super classes.

Saturday, August 13, 2016

What is the difference between string and text types in rails migration?

The :string type is used for short text input such as text fields, drop downs, select boxes etc. The :text is used for long text such as text area.

How to rename a database column in Rails migration?

If you have not deployed the code to any environment, you can roll back the migration.

rake db:rollback

And create the migration with the right column by correcting the column name. If you have lot of data that you don't want to lose then renaming is the way to go.

Generate a new migration file for renaming the old column:

rails g migration RenameOldColumnToNewColumn
Then modify the change method in the generated migration file:

rename_column :table_name, :old_column, :new_column

rails generator for model with belongs_to

Comment belongs to a user.

rails g model comment content:text user:references

This command will automatically add the belongs_to in comment model. If you generate the model like this:

rails g model comment content:text user_id:integer

Rails will not add the belongs_to to the comment model. You have to do it manually.

How to run rails generate scaffold when the model already exists?

rails g scaffold article --skip

How to delete all data and recreate a database tables in Rails?

You can drop the database by:

rake db:drop
This will delete the database.

You can create the database by:

rake db:create
You can create all the tables in the database by:

rake db:migrate
You can combine all three commands database by:

rake db:drop db:create db:migrate
You can accomplish it with just one rake task by:

rake db:schema:load
This loads the schema.rb file into the database.

This rake task is dangerous. It is useful only in development environment only. Do not run in any other environment other than development.

Friday, August 12, 2016

How to get the Rails app root directory path in Rails console?

You can get the Rails app root directory path in Rails console like this:

rails c
Loading development environment (Rails 5.0.0)
>> Rails.root
=> #
>> Rails.root.class
=> Pathname

You can get any path in your Rails app by using join method:

>> Rails.root.join('app', 'assets')
=> #

You have to call to_s to get a string like this:

>> Rails.root.join('app', 'assets').to_s
=> "/Users/zepho/temp/zurb/app/assets"


How to roll back a migration file in Rails?

Rollback by Given Number of Steps

You can list all the rake tasks in Rails 5 by doing:

rake db -T | grep rollback
Rolls the schema back to the previous version (specify steps w/ STEP=n)

rake db:rollback           
This rollbacks by one version. You can use:

rake db:rollback  STEP=2
to revert the last two migrations and so on. 

Rollback to a Specific Version

Provide the version to db:migrate down:

rake db:migrate down VERSION=20160206120000
You can also go up to a given version:

rake db:migrate up VERSION=20160206120000

How to remove a column from a table in Rails console?

>> ActiveRecord::Migration.remove_column(:products, :price)
-- remove_column(:products, :price)
   (0.1ms)  begin transaction
   (0.7ms)  CREATE TEMPORARY TABLE "aproducts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "price" decimal, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
   (0.4ms)  INSERT INTO "aproducts" ("id","name","price","created_at","updated_at")
                     SELECT "id","name","price","created_at","updated_at" FROM "products"
   (0.3ms)  DROP TABLE "products"
   (0.2ms)  CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
   (0.1ms)  INSERT INTO "products" ("id","name","created_at","updated_at")
                     SELECT "id","name","created_at","updated_at" FROM "aproducts"
   (0.2ms)  DROP TABLE "aproducts"
   (49.8ms)  commit transaction
   -> 0.0624s
=> []
 

You have to exit the Rails console and go into Rails console again:

rails c
Loading development environment (Rails 5.0.0)
>> Product.columns.map{ |c| [c.name, c.type]}
=> [["id", :integer], ["name", :string], ["created_at", :datetime], ["updated_at", :datetime]]

You can now see that the price column has been removed from the products table.


How to drop a table using Rails database migration in the console?

In Rails 5, you can go to the console and do this:

ActiveRecord::Migration.drop_table(:products)
- drop_table(:products)
   (29.8ms)  DROP TABLE "products"
   -> 0.0303s
=> []
If you list the tables, you will see that products table is no longer in the database:

>> ActiveRecord::Base.connection.data_sources
=> ["schema_migrations", "ar_internal_metadata"]

How to list the tables and the table structure in Rails console?

In Rails 5:

The tables method has been deprecated:

ActiveRecord::Base.connection.tables
DEPRECATION WARNING: #tables currently returns both tables and views. This behavior is deprecated and will be changed with Rails 5.1 to only return tables. Use #data_sources instead. (called from irb_binding at (irb):2)

So, you can list all the tables like this:

> ActiveRecord::Base.connection.data_sources
=> ["schema_migrations", "ar_internal_metadata", "products"]

You can then list the columns and it's type like this:

Product.columns.map{ |c| [c.name, c.type]}
=> 
[["id", :integer], 
["name", :string], 
["price", :decimal], 
["created_at", :datetime], 
["updated_at", :datetime]]




How to get the current absolute URL in Rails

Absolute URL in Rails

In Rails 5, you can use:

request.original_url

Assuming, the request is:

get "/articles?page=2"

This will return:

http://www.example.com/articles?page=2

This is defined in actionpack/lib/action_dispatch/http/request.rb.

Full path without the URL

For this request:

get "/articles"

request.fullpath 

will return:

/articles

For a request with params in the URL:

get "/articles?page=2"

It will return:

/articles?page=2







Undo Scaffolding in Rails

You can undo the scaffold command by using the destroy. You should also rollback the database transaction, if you have already run the migration generated by that scaffold.

rails destroy scaffold 'myscaffold'
rake db:rollback



Wednesday, August 10, 2016

Rails Screencast Live on iTunes

Subscribe to the free Rails Screencasts on iTunes. The first 3 episodes builds a Movie Review database using Rails 5, Twitter Bootstrap 4, Searchkick and Elasticsearch.

Monday, August 08, 2016

Zurb Foundation with Rails 5









How to Learn Anything Quickly

Meetup Notes from Silicon Valley Ruby Meetup How to Learn Anything Quickly.

You don't know that you don't know

Here is an example. I knew that I did not know Box Model. I did not know that I don't know CSS animations. During the step 1, get the big picture stage you will find out there are things that you did not know you don't know. Is CSS animations relevant to my learning project? You don't need to spend time learning that topic to decide whether you want to learn it.

Broad Topics

Topics that are too broad are not feasible to learn within a few weeks. Example: Ruby Meta-programming. Break it down. I will have learned the basics of Ruby meta-programming when I can develop a Sinatra clone. This learning project can fit into a 4-6 weeks time frame.

Sequence of the 10 Steps

You cannot change the sequence of some of the steps. For instance, play around step must come before 'Learn enough to do something useful' step. Play around step primes the pump. It prepares your brain to become receptive to the new knowledge you will gain in the step 9 (Learn enough to do something useful).

What if step 3, define success is step 1? If the step 3 is the first step, you may end up with a success criteria that is too big due to lack of proper scope.

What if the activity for play around step, if it's not a GUI tool? 

For instance, learning CSS does not have any complicated GUI tool that you can play around. The objective of play around step is to come up with focus questions. For learning CSS, take the one page hand drawn paper prototype and come up with as many focus questions as you can. You can get help from someone who knows CSS.

- How do I center the main content?
- How do I create the navigation bar?
- How do I display the image to the left?

I find my topic difficult to learn.

Learning a new topic is like lifting weights. You are not going to become a Olympic champion in a few weeks. You can raise the level of difficulty of your learning projects over time. Build on top of successes. You will find the material difficult to learn if you don't have the pre-requisite knowledge. If you break down the topic into smaller chunks that takes 5 to 10 mins, you can probably finish it between other tasks during the day.

What if I am learning to keep up with new tech?

Learn the new tech using the 10 step process to build a reference project. Why? Because you can use another technology to build the same reference project. This will allow you to compare different technology to weigh it's advantages and disadvantages. Think Java Pet Store sample app for J2EE platform. You can answer questions like:

- What is the learning curve like?
- How easy is it to setup?
- How well is it documented?
- How is the support from the developer community?

What if all the different fields are equally important?

Pick one. If you have difficulty in choosing the first one to focus on, use pair ranking to decide. I developed a pair ranking gem.

Beginner's Mind

You can draw anything in a blank canvas. Be open to new ideas. Don't have preconceived notion or bias. Avoid things like, you can do it in a better way using [insert your favorite language / framework here]. You need to have a beginner's state of mind.

Progression of Topics 

As an example, here is the progression for a new Rails developer learning Ruby :

1. How to install Ruby and Ruby version manager.
2. How to play with IRB?
3. Basic data structures such as Hash, Array
4. Control Flow

Friday, August 05, 2016

rails content_tag_for

Do not use the rails content_tag_for. Just use html with embedded Ruby. Read the Beautiful Markup RailsConf 2010 presentation for more details. It has been removed from rails and is now available as record_tag_helper gem.

Usage:
<%= content_tag_for(:tr, @article) do %>
  <td><%= @article.title %></td>
<% end %> 

Generates:

<tr id="article_1234" class="article">
  <td>Hello World!</td>
</tr>



Thursday, August 04, 2016

rails div_for

This:

<%= div_for(@article, class: "frontpage") do %>
  <td><%= @article.title %></td>
<% end %>

Becomes:

<div id="article_1234" class="article frontpage">
  <td>Hello World!</td>
</div>

This has been deprecated. It is also not a good practice to use the div_for tag. Why? Checkout the: Beautiful Markup Rails Conf Presentation slides. If you really need it, it is now part of the record_tag_helper gem.