In this article is for newer developers looking to learn strategy and commands on Rails. When I started to learn ruby on rails; I kept going back and looking up how to use certain generators.
Rails is a web application development framework written in the Ruby programming language and was designed to make programming web applications easier. It allows you to write less code while accomplishing more than any frameworks.
First, install the Rails gem if you haven't done so.
gem install rails "rails generate" is the same as "rails g"
Rails Generate
rails g Running this command outputs all of the available generators.
- application_record - assets - benchmark - channel - controller - generator - helper - integration_test - jbuilder - job - mailbox - migration - model - resource - scaffold - scaffold_controller - system_test - task Models
rails g model "rails g model NameOfYourModel field1:data_type field2:date_type"
A model is a Ruby class that is used to represent data and can interact with application's database through a feature of Rails called Active Record. It creates both the model and the migration.
Model names are singular, because an instantiated model represents a single data record.
The generator adds timestamps by default(created_at and updated_at). Also the default type of an attribute is string so you don't have to include it. If I put name in field; it will be treated as name:string.
A generator will include the :password_digest field in the migration and the has_secure_password method in the model; if you include password:digest when generating a model.
Another neat thing rails does for us is when adding reference to a field generates an id column, which does a belongs_to associations for us.
# generates the Product migration with a foreign id for Seller rails g model Product name description:text seller:references It will create a migration that looks like this
class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :name t.text :description t.references :seller, null: false, foreign_key: true t.timestamps end end # and the Seller model, with the association class Product < ApplicationRecord belongs_to :seller end When making any adjustments you need to run rails db:migrate after the changes.
Migrations
A Rails migration is a tool for changing and modifying an application's database schema.
Migration Data Types
:primary_key - translates into whatever the primary key datatype your database of choice requires :string - use for short strings such as names and emails :text - use for long strings, normally captured by textarea :integer - it’s a whole number, eg. 0,12,12532 :float - decimal numbers stored with fixed floating point precision :decimal - stored precision varies; good for exact math calculations :datetime - both date and time :timestamp - same as datetime; usually used for created_at/updated_at :time - hours, minutes, seconds :date - year, month, day :binary - store images, videos and other files in their original format in chunks of data called blobs :blob - similar to binary, contains the metadata about a file. Blobs are intended to be immutable :boolean - self explanatory - true/false :json - from Rails 5 onwards, you can natively store JSON values thanks to this Pull Request. A lot of people still use Postgres’ jsonb datatype though. Active Record provides methods that perform common data definition tasks
- add_column - add_index - change_column - change_table - create_table - drop_table - remove_column - remove_index - rename_column If the migration name is of the form AddXToY or RemoveXFromY and is followed by a list of column names and types then a migration containing the appropriate add_column and remove_column statements will be created.
rails g migration AddPriceToProduct price:integer # generates the following migration class AddPriceToProduct < ActiveRecord::Migration[6.1] def change add_column :products, :price, :integer end end Controller
rails g controller "rails g controller NameOfController action1 action2 ..."
Action Controller is the C in MVC. The controller is responsible for making sense of the request and producing the appropriate output which, does most of the groundwork for you. You can think of the controller being the middleman between models and views. It makes the model data available to the view, so it can display that data to the user and saves/updates user data to the model.
The naming convention of controllers in Rails favors pluralization of the last work in the controller's name, although it is not strictly required.
# generates a controller and actions... rails g controller Products index show update destroy class ProductsController < ApplicationController def index end def show end def update end def destroy end ene # and routes in the routes.rb file Rails.application.routes.draw do get ‘products/index’ get ‘products/show’ get ‘products/new’ get ‘products/edit’ end A good to know, to generate just the controller file, without all the extra files and folders use the following:
rails generate controller ControllerName index show new edit --no-helper --no-assets --no-test-framework --skip-routes --skip Resource
$ rails g resource --no-test-framework # --no-test-framework will not install the test files "rails g resource NameOfResource field:data_type field:data_type"
Each of the previous generators, resource does it in one command. It will create a model, does the migration, have an empty controller(for your actions), and have full CRUD routes in your routes.rb
rails g resource Product name description:text price:integer --no-test-framework invoke active_record create db/migrate/20200326023754_create_products.rb create app/models/product.rb invoke controller create app/controllers/products_controller.rb invoke erb create app/views/products invoke helper create app/helpers/products_helper.rb invoke assets invoke scss create app/assets/stylesheets/products.scss invoke resource_route route resources :products This will create the following:
# creates a migration... in db/migrate/20190714193807_products.rb class CreateProducts < ActiveRecord::Migration[6.1] def change create_table :products do |t| t.string :name t.string :capital t.timestamps end end end # a model... class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :name t.text :description t.integer :price t.timestamps end end # a controller... class TerritoriesController < ApplicationController end #config/routes.rb Rails.application.routes.draw do resources :products end As you can see this tool saves you time when you're doing a code challenge or want to do all the action in one command.
Scaffold would set up everything for you as well just as, routes, controller, views, models, and migrations.
rails g scaffold
More Info
# Run migration $ rails db:migrate # Rollback last migration $ rails db:rollback # Run database seed code $ rails db:seed # Delete and re-create db and run migrations $ rails db:reset Routes
# Route maps to controller#action get 'welcome', to: 'products#home' # Root page (root_path name helper) root 'products#home' # Named route get 'exit', to: 'sessions#destroy', as: :logout # Create all the routes for a RESTful resource resources :items HTTP Verb Path
# HTTP Verb Path Controller#Action Named Helper # GET /items items#index items_path # GET /items/new items#new new_item_path # POST /items items#create items_path # GET /items/:id items#show item_path(:id) # GET /items/:id/edit items#edit edit_item_path(:id) # PUT /items/:id items#update item_path(:id) # DELETE /items/:id items#destroy item_path(:id) # Only for certain actions resources :items, only: :index # Resource with exceptions resources :items, except: [:new, :create] # Nested resources resources :items do resources :reviews end # Dynamic segment: params['id'] get 'products/:id', to: 'products#show' # Query String: url /products/1?user_id=2 # params will be {'id' 'user_id'} Model Validation examples
# Model validation validates :title, :description, :image_url, presence: true validates :email, presence: true, format: { with: /\A[^@\s]+@[^@\s]+\z/, message: 'Must be a valid email address'} validates :price, numericality: { greater_than_equal_to: 0.01 } validates :title, uniqueness: true validates :title, length: { minimum: 3, maximum: 100 } validates :type, inclusion: types.keys # Model relationship belongs_to :customer # Relation with cascade delete has_many :invoices, dependent: :destroy #One to one has_one :profile # Hook methods before_destroy :ensure_not_reference_by_any_invoices before_save :downcase_email Active Record
# Active record common methods Article.all # Throw error if not found Article.find(params[:id]) # Do not throw error if not found Article.find_by(product_id: product_id) @category = Category.find_by!(slug: params['slug']) # Return Not Found Error (404 page in production) Article.group(:product_id).sum(:quantity) Article.where('quantity > 1') Article.where(cat_id: cat_id, model: model) Article.where(model: model).or(Article.where(cat_id: cat_id)) Article.join(:categories).where(categories: { id: 2 } ) Article.where("title LIKE ?", "%" + params[:q] + "%") Article.count Article.first Article.last Article.column_names # ['id', 'name', 'price'] Category.delete_all # delete all rows in Category table product.category = Category.all.sample # random for Faker data @products = Product.offset(5).limit(10).all # skip 5, take 10 # Create flash (reset every new request) flash[:success] = 'User created with success!' # Create flash.now (reset every new view render) flash.now[:error] = 'Please select s user!' # Create session (reset every browser close) session[:user_id] = user.id # Check if session exist session[:user_id].nil? # Remove session.delete(:user_id) # Remove all reset_session # Create cookie (reset at expiration date) cookies.permanent[:remember_token] = remember_token # Encrypted cookie cookies.permanent.encrypted[:user_id] = user.id # Delete cookie cookies.delete(:user_id) Deployment with Heroku
# Create git and push to Heroku $ heroku create $ git remote $ bundle install --without production $ git status $ git add -A $ git commit -m 'heroku deployment' $ git push origin master $ git push heroku master $ heroku run rails db:migrate $ heroku run rails db:seed # launch the upload site $ heroku open Rails CLI
# Create a new rails app $ rails new project_name # Start the Rails server $ rails s # Rails console $ rails c # Install dependencies $ bundle install # View all routes $ rails routes Files
--no-test-framework — prevents generator from creating standard tests
--skip — skips files that already exist
--no-assets — prevents generator from creating assets
--no-helper — prevents generator from creating helper
--skip-routes — prevents generator from adding routes to routes.rb
I hope you can take some info and apply into your code. Thank you for reading and best wishes.
Top comments (4)
Thanks...
It would be interesting to bring us rollback commands.
@vitor0liveir4 what exactly do you mean?
You can "rollback" using
rails destroy ...(orrails d ...) just like usingrails generate ...(orrails g ...).E.g.
rails g model Product name description:textcan be removed withrails d model Product.@fwolfst What I mean would be thinking about reversing the changes about using something wrong before, and you want to undo it or something like that… By the way, your answer makes sense! Tky!!