rails new app_name --options-flags
3 2 1
rails g model Song title:string year:integer
app/models/song.rb
db/migrate/95347573749_create_songs.rb
rails db:migrate
rails g migration AddCategoryToSongs category:string
db/migrate/20190301204229_add_category_to_songs.rb
rails db:migrate
class Song < ApplicationRecord
validates :title, presence: true
end
song = Song.new(name: '')
song.valid?
# => false
song.errors
# => an error object with more info
3 1 2 4
VERB (GET, POST, PATCH, DELETE, ....)
URL (procotol/host or domain/path/query)
HEADERS (stuff... user agent, authentication, etc)
BODY (content)
No, because the verb is different.
GET intends to request information, POST intends to send information.
# params[:query] => 'thriller'
@songs = Song.where(title: params[:query])
# params[:name] => 'thriller'
@songs = Song.where(title: params[:name])
# Create
get 'songs/new', to: 'songs#new'
post 'songs', to: 'songs#create'
# Read
get 'songs', to: 'songs#index'
get 'songs/:id' to: 'songs#show', as: 'song'
# Update
get 'songs/:id/edit', to: 'songs#edit'
patch 'songs/:id', to: 'songs#update'
# Destroy
delete 'songs/:id', to: 'songs#destroy'
rails routes
rails g controller Songs
def show
@song = Song.find(params[:id])
end
def index
@songs = Song.all
end
def new
@song = Song.new
end
def create
@song = Song.new(song_params)
if @song.save
redirect_to @song
else
render :new
end
end
def song_params
params.require(:song).permit(:title, :year, :category)
end
It's unsafe to fully trust the parameters that user sends.
action -> 'songs'
name -> 'song[title]'
value -> ''
action -> 'songs/18'
name -> 'song[title]'
value -> 'Hey Jude'
rails g model review content song:references
rails db:migrate
class Song < ApplicationRecord
has_many :reviews
end
class Review < ApplicationRecord
belongs_to :song
validates :content, presence: true
end
rails g controller reviews new create
resources :songs do
resources :reviews, only: [:new, :create]
# Next line creates an array of symbols
# %i[new create]
end
def new
@review = Review.new
end
def create
@review = Review.new(review_params)
@review.song = @song
if @review.save
redirect_to @song
else
render :new
# render 'songs/show' # <- in case the form for a new review was in the song show page
end
end
<% @song.reviews.each do |review| %>
<p><%= review.content %></p>
<% end %>