Skip to content

Instantly share code, notes, and snippets.

@yoyozi
Last active July 26, 2017 23:40
Show Gist options
  • Save yoyozi/9dc859451da93e97dcd61150f6af1a3b to your computer and use it in GitHub Desktop.
Save yoyozi/9dc859451da93e97dcd61150f6af1a3b to your computer and use it in GitHub Desktop.
gem install rails -v 5.0.0
Adding referance to migration
rails g migration AddUserToUploads user:references
rails g scaffold Tool name:string description:text
rails g migration AddToolToUsdzar tool:references
> rails g model user email:string:unique password_digest:string
to remove
> rails d model user email:string:unique password_digest:string
> rails g model user email:string:uniq password_digest:string
with uniq gives you indexing
rails g migration add_columns_to_users admin:boolean firstname:string lastname:string
Controller Plural
rails g controller Users index show
Helper Plural
rails g helper Users
Mailer Singular
rails g mailer UserMailer
Migration Plural
rails g migration AddEmailToUsers email:string
Model Singular
rails g model User name:string
Observer Singular
rails g observer User
Resource Plural*
resources :users, :only => [:index, :show]
Scaffold Singular
rails g scaffold User name:string
rails g scaffold Tool name:string description:text
Table Plural
SELECT * FROM users;
URL Action Purpose
/users index page to list all users
/users/1 show page to show user with id 1
/users/new new page to make a new user
/users/1/edit edit page to edit user with id 1
HTTP request URL Action Purpose
GET /users index page to list all users
GET /users/1 show page to show user with id 1
GET /users/new new page to make a new user
POST /users create create a new user
GET /users/1/edit edit page to edit user with id 1
PATCH /users/1 update update user with id 1
DELETE /users/1 destroy delete user with id 1
rake db:create # Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)
rake db:drop # Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)
rake db:fixtures:load # Load fixtures into the current environment's database
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false)
rake db:migrate:status # Display status of migrations
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR
rake db:schema:load # Load a schema.rb file into the database
rake db:seed # Load the seed data from db/seeds.rb
rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)
rake db:structure:dump # Dump the database structure to db/structure.sql
rake db:version # Retrieves the current schema version number
Scaffolding
$ rails generate scaffold User name:string email:string
Weaknesses of this Users resource
Though good for getting a general overview of Rails, the scaffold Users
resource suffers from a number of severe weaknesses.
No data validations. Our User model accepts data such as blank names and
invalid email addresses without complaint.
No authentication. We have no notion of logging in or out, and no way to
prevent any user from performing any operation.
No tests. This isn’t technically true—the scaffolding includes rudimentary
tests—but the generated tests don’t test for data validation, authentication,
or any other custom requirements.
No style or layout. There is no consistent site styling or navigation.
No real understanding. If you understand the scaffold code, you probably
shouldn’t be reading this book.
$ rails generate scaffold Micropost content:text user_id:integer
$ rails db:migrate
EDIT the routes
Rails.application.routes.draw do
resources :microposts
resources :users
root 'users#index'
end
Validation
class Micropost < ApplicationRecord
validates :content, length: { maximum: 140 }
end
EDIT MODELS to give relationships
class User < ApplicationRecord
has_many :microposts
end
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 }
end
Validate presence of post
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 },
presence: true
end
User modeling validation and presence of posts
class User < ApplicationRecord
has_many :microposts
validates FILL_IN, presence: true # Replace FILL_IN with the right code.
validates FILL_IN, presence: true # Replace FILL_IN with the right code.
end
Full command Shortcut
$ rails server $ rails s
$ rails console $ rails c
$ rails generate $ rails g
$ rails test $ rails t
$ bundle install $ bundle
Undoing things
$ rails generate controller StaticPages home help
$ rails destroy controller StaticPages home help
$ rails generate model User name:string email:string
This can be undone using
$ rails destroy model User
$ rails db:migrate
We can undo a single migration step using
$ rails db:rollback
To go all the way back to the beginning, we can use
$ rails db:migrate VERSION=0
Generating static named pages in place of default
$ rails generate controller StaticPages home help
Rails.application.routes.draw do
get 'static_pages/home'
get 'static_pages/help'
root 'application#hello'
end
So the controller looks like:
class StaticPagesController < ApplicationController
def home
end
def help
end
end
This creates as standard
app/views/static_pages/home.html.erb
<h1>StaticPages#home</h1>
<p>Find me in app/views/static_pages/home.html.erb</p>
and
app/views/static_pages/help.html.erb
<h1>StaticPages#help</h1>
<p>Find me in app/views/static_pages/help.html.erb</p>
Testing
Controller tests
$ ls test/controllers/
static_pages_controller_test.rb
Let’s take a look at it (Listing 3.13).
The default tests for the StaticPages controller. green
test/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
end
test "should get help" do
get static_pages_help_url
assert_response :success
end
end
Then run rails test
Page URL Base title Variable title
Home /static_pages/home "Ruby on Rails Tutorial Sample App" "Home"
Help /static_pages/help "Ruby on Rails Tutorial Sample App" "Help"
About /static_pages/about "Ruby on Rails Tutorial Sample App" "About"
Testing TITLES
<!DOCTYPE html>
<html>
<head>
<title>Greeting</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
We’ll write simple tests for each of the titles in Table 3.2 by combining the
tests in Listing 3.15 with the assert_select method, which lets us test for the
presence of a particular HTML tag (sometimes called a “selector”, hence the
name):11
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
In particular, the code above checks for the presence of a <title> tag
containing the string “Home | Ruby on Rails Tutorial Sample App”. Applying this
idea to all three static pages gives the tests shown in Listing 3.24.
Listing 3.24: The Static Pages controller test with title tests. red
test/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
end
test "should get help" do
get static_pages_help_url
assert_response :success
assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
end
test "should get about" do
get static_pages_about_url
assert_response :success
assert_select "title", "About | Ruby on Rails Tutorial Sample App"
end
end
$ rails test
3 tests, 6 assertions, 3 failures, 0 errors, 0 skips
3.4.2 Adding page titles (Green)
Code Matching HTML
assert_select "div" <div>foobar</div>
assert_select "div", "foobar" <div>foobar</div>
assert_select "div.nav" <div class="nav">foobar</div>
assert_select "div#profile" <div id="profile">foobar</div>
assert_select "div[name=yo]" <div name="yo">hey</div>
assert_select "a[href=?]", ’/’, count: 1 <a href="/">foo</a>
assert_select "a[href=?]", ’/’, text: "foo" <a href="/">foo</a>
Table 5.2: Some uses of assert_select.
Now we’ll add a title to each page, getting the tests from Section 3.4.1 to
pass in the process. Applying the basic HTML structure from Listing 3.23 to the
custom Home page from Listing 3.11 yields Listing 3.26.
The view for the Home page with full HTML structure. red
app/views/static_pages/home.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Home | Ruby on Rails Tutorial Sample App</title>
</head>
<body>
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
sample application.
</p>
</body>
</html>
Listing 3.30: The Static Pages controller test with a base title. green
test/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
def setup
@base_title = "Ruby on Rails Tutorial Sample App"
end
test "should get home" do
get static_pages_home_url
assert_response :success
assert_select "title", "Home | #{@base_title}"
end
test "should get help" do
get static_pages_help_url
assert_response :success
assert_select "title", "Help | #{@base_title}"
end
test "should get about" do
get static_pages_about_url
assert_response :success
assert_select "title", "About | #{@base_title}"
end
end
Layouts and embedded Ruby (Refactor)
app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<!DOCTYPE html>
<html>
<head>
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
</head>
<body>
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
sample application.
</p>
</body>
</html>
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all'
'data-turbolinks-track': 'reload'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track' 'reload'
%>
</head>
<body>
</body>
<%= yield %>
</html>
Now change layout to hold normal structure and home relevant to the change
app/views/static_pages/home.html.erb
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a>
sample application.
</p>
Automated tests with Guard
One annoyance associated with using the rails test command is having to switch
to the command line and run the tests by hand. To avoid this inconvenience, we
can use Guard to automate the running of the tests.
$ bundle exec guard init
Tell gaurd what to keep testing
the matching rules for Guard.
guard :minitest, spring: true, all_on_start: false do
watch(%r{^test/(.*)/?(.*)_test\.rb$})
watch('test/test_helper.rb') { 'test' }
watch('config/routes.rb') { integration_tests }
watch(%r{^app/models/(.*?)\.rb$}) do |matches|
"test/models/#{matches[1]}_test.rb"
end
watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches|
resource_tests(matches[1])
end
watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches|
["test/controllers/#{matches[1]}_controller_test.rb"] +
integration_tests(matches[1])
end
watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches|
integration_tests(matches[1])
end
watch('app/views/layouts/application.html.erb') do
'test/integration/site_layout_test.rb'
end
watch('app/helpers/sessions_helper.rb') do
integration_tests << 'test/helpers/sessions_helper_test.rb'
end
watch('app/controllers/sessions_controller.rb') do
['test/controllers/sessions_controller_test.rb',
'test/integration/users_login_test.rb']
end
watch('app/controllers/account_activations_controller.rb') do
'test/integration/users_signup_test.rb'
end
watch(%r{app/views/users/*}) do
resource_tests('users') +
['test/integration/microposts_interface_test.rb']
end
end
# Returns the integration tests corresponding to the given resource.
def integration_tests(resource = :all)
if resource == :all
Dir["test/integration/*"]
else
Dir["test/integration/#{resource}_*.rb"]
end
end
# Returns the controller tests corresponding to the given
resource.
def controller_test(resource)
"test/controllers/#{resource}_controller_test.rb"
end
# Returns all tests for the given resource.
def resource_tests(resource)
integration_tests(resource) << controller_test(resource)
end
Here the line
guard :minitest, spring: true, all_on_start: false do
causes Guard to use the Spring server supplied by Rails to speed up loading
times, while also preventing Guard from running the full test suite upon
starting.
Adding Spring to the .gitignore file.
See https://help.github.com/articles/ignoring-files for more about
ignoring files.
If you find yourself ignoring temporary files generated by your text editor
or operating system, you probably want to add a global ignore instead:
git config --global core.excludesfile '~/.gitignore_global'
Ignore bundler config.
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
# Ignore Byebug command history file.
.byebug_history
# Ignore Spring files.
/spring/*.pid
HELPERS : Titale helper
module ApplicationHelper
Returns the full title on a per-page basis.
def full_title(page_title = '')
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
page_title + " | " + base_title
end
end
end
Tdhen in html file use
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
And in an example
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all',
'data-turbolinks-track': 'reload'%>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
%>
</head>
<body>
<%= yield %>
</body>
</html>
An updated test for the Home page’s title. red
test/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
assert_select "title", "Ruby on Rails Tutorial Sample App"
end
test "should get help" do
get static_pages_help_url
assert_response :success
assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
end
test "should get about" do
get static_pages_about_url
assert_response :success
assert_select "title", "About | Ruby on Rails Tutorial Sample App"
end
end
Rails environments
Rails comes equipped with three environments: test, development, and
production. The default environment for the Rails console is development:
$ rails console
Loading development environment
.env "development"
.env.development?
true
.env.test?
=> false
As you can see, Rails provides a Rails object with an envattribute and
associated environment boolean methods, so
that, for example, Rails.env.test? returns true in a testenvironment and false
otherwise.
If you ever need to run a console in a differentenvironment (to debug a test,
for example), you can pass
the environment as a parameter to the console script:
$ rails console test
Loading test environment
Rails.env
"test"
Rails.env.test?
=> true
As with the console, development is the
default environment for the Rails
server, but you can also run it in
a different environment:
$ rails server --environment production If you view your app running in
production, it won’t work without a production database, which we can create
by running rails db:migrate in production:
$ rails db:migrate RAILS_ENV=production
(I find it confusing that the idiomatic commands to run the console, server,
and migrate commands in non-default environments use different syntax, which is
why I bothered showing all three. It’s worth noting, though, that preceding
any of them with RAILS_ENV=<env> will also work, as in RAILS_ENV=production
rails server).
RESETTING Data in DB
rails db:migrate:reset
config/environments/production.rb
Rails.application.configure do
# Force all access to the app over SSL, use Strict-Transport-Security,
# and use secure cookies.
config.force_ssl = true
Generate a session controller
rails generate controller Sessions new
Since we’ve now added several custom named routes, it’s useful to look at the
complete list of the routes for our application, which we can generate using
rails routes:
$ rails routes
SESSION generation
rails generate controller Sessions new
TESTING one file and then a particular test
rails test test/integration/users_login_test.rb
$ rails test test/integration/users_login_test.rb --name
test/integration/users_login_test.rb
Persistant cookies
$ rails generate migration add_remember_digest_to_users remember_digest:string
ACTIVATION token
$ rails generate migration add_activation_to_users activation_digest:string
activated:boolean activated_at:datetime
Migrate to previous version
rake db:rollback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment