Rails
Fundamental Rail Commands:
rails new PROJECT_NAME # creat eall files
rails s -b 0.0.0.0 # boots up server, listen for request on port 3000
Route -> Controller -> View
- define routes
- handler methods in controller
- write view templates in the view file
Route
-
Key value pair
(key, value)
(HTTP_method, "url_pattern")
get '/posts/:id', to: 'posts#show'
-
Model
Post
-
In
routes.rb: get '/posts', to: 'posts#show'
(ClassName#method_name, “Controller” is omitted) -
In
posts_controller.rb: class PostsController
-
In
/views/posts: show.html.erb
Controller
- All controller methods have access to
params
hash
Params Hash contains all the information of the request.
View
app/views/#{resource_name}/#{action_name}.html.erb
Embedded Ruby in HTML
<ul>
<% @posts.each do |post| %>
<li>
<a href = "<%= post.url%>"><%= post.title %></a>
</li>
<% end %>
</ul>
<% ... %>
gets evaluated but not rendered.<%= ... %>
gets evaluated and rendered.
ERB Structure
- ‘<%= yield %>’ to load the “current” erb file
- ERB is modilarized and just includes
<body>
section
ERB Partial
- Underscore for partial:
_post.html.erb
<%# In /posts/index.html.erb %>
<% @posts.each do |post| %>
<%= render 'post', @post: post %>
<% end %>
<%# In /posts/_post.html.erb %>
<h1><%= @post.title %></h1>
<p><%= @post.body %></p>
ERB Helpers
<%# DELETE AND PATCH requests %>
<%# generate an <a> tag that triggers the browser to perform the method %>
<%= link_to "link-text", "path", method: "http_method" %>
<%= link_to "Delete Book", "/books/#{@book.id}", method: "delete" %>
<%# PUT requests %>
<%# generate a form %>
<%+ form_with ... %>
<%# generate an <img> tag %>
<%= image_tag("image_name") %>
Redirection and Render
def create
...
if @post.save
redirect_to "/posts/#{@post.id}" # make a new request to the path
else
render :new # display view file of controller method (in this case new)
end
end
Quick Debugging Steps
- syntatic check of
route.rb
- check if requests hit the correct handler method
binding.pry
to set break points- inspect
params
at break points
- write simple html in erb to check if variables in controller method pass through
Migration -> Database <-> Model (CRUD)
Dual representation
@post = Post.new({title: 'hello', body: 'world'}) #save in-memory /models/posts.rb
@post.save #save in-database /db/schema.rb
Generating dual representtaion
Migration is a one-time change
- Next migration ignores the same migration
- deleting existing migration file doesn’t remove the effect of the migration
To change model, generate a migration instead of changing model.rb!
rails g model ModelName fieldName:fieldType ... # generate model and migration file
rails db:migrate # initialize/updates the schema.rb
# add columns
rails g migration AddFieldnameToTablename fieldName:fieldType ...
# remove columns
rails g migration RemoveFieldnameFromTablename fieldName:fieldType ...
# create table
rails g model ModelName fieldName:fieldType ...
CRUD APIs provided by model file
- Create
@post = Post.new({title: "title", body: "..."})
@post.save
# OR:
Post.create({title: "title", body: "..."})
- Read
@posts = Post.all
@post = Post.find(1)
- Update
@post = Post.find(1)
@post.title = "new_title"
@post.save
# OR:
@post = Post.find(1)
@post.update({title: "new_title"})
- Delete
@post = Post.find(1)
@post.destroy
Quick Debugging Steps
-
always use generator for models and migration
- if
rails g
command goes wrong, run the same command withrails destroy + same commands
- if
-
don’t forget
rails db:migrate
rails db:drop
to destroy the database entirely (only for development)
-
check
schema.rb
to see if the table structure matches expectation -
use
rails c
to check if CRUD API works- irb environment
Gemfile
Every modification to Gemfile
requires to run bundle install
Web deployment Heroku