rails new NOM_DE_L_APP
rails new NOM_DE_L_APP --webpack
rails new NOM_DE_L_APP --database=postgres- Coding the views?
- Coding the controllers?
- Coding the models?
π 3 - 2 - 1
rails generate model song title year:integerWhat are the 2 created files?
π The migration and the model.
What is the rails command you should type then?
rails db:migrateQ4 - How do you add a category (ex: "rock" , "electro" , etc..) to your songs table using the correct Rails generator?
rails g migration AddCategoryToSongs categoryWhat is the created file?
π a new migration
What is the rails command you should type again?
rails db:migrate# models/song.rb
class Song < ApplicationRecord # Add the validation
validates :title, presence: :true
endNow crash-test your model:
song = Song.new
song.valid?
song.errors.messages
song.title = "hey jude"
song.save- The Router is routing the HTTP request to "controller#action"
- The action is getting data from models
- Everything starts with an HTTP Request
- The action is rendering the view
π 3 - 1 - 2 - 4
- Verb
- Url
- Header
- Body
# config/routes.rb
get "/songs" => "songs#index"
post "/songs" => "songs#create"π No, verbs are differents.
π GET requests have no body. Data can only be sent via the url's query string (visible to users)
HTTP request: GET /search?query=thriller
Routing:
# config/routes.rb
get "/search" => "songs#search"Controller:
class SongsController < ApplicationController
def search
# TODO
@songs = Song.where(title: params[:query])
end
endHTTP request: GET /songs/named/thriller
Routing:
# config/routes.rb
get "/songs/named/:name" => "songs#search"Controller:
class SongsController < ApplicationController
def search
# TODO
@songs = Song.where(title: params[:name])
end
end# config/routes.rb
# TODO: Give us the details of the 7 routes generated with: resources :songs
# HINT: HTTP-verb "url" => "controller#action"
get "/songs", to: "songs#index"
get "/songs/:id", to: "songs#show"
get "/songs/new", to: "songs#new"
post "/songs", to: "songs#create"
get "songs/:id/edit", to: "songs#edit"
patch "songs/:id", to: "songs#update"
delete "songs/:id", to: "songs#destroy"rails routesrails generate controller songsclass SongsController < ApplicationController
def index
@songs = Song.all
end
def show
@song = Song.find(params[:id])
end
endQ16 - What are the 2 requests needed to create a new song? Implement the songs#new and songs#create actions.
class SongsController < ApplicationController
def new
@song = Song.new
end
def create
@song = Song.new(song_params)
if @song.save
redirect_to songs_path
else
render 'new'
end
end
private
def song_params
params.require(:song).permit(:title, :year, :category)
end
endπ Any user can add inputs in the HTML using the browser's inspector before submitting a form. If you guess that Github has an admin boolean column to its users table, you could tweak the edit form to grant yourself admin rights on Github π± This actually happened in 2012 when Github was on Rails 2, which led to the strong params from Rails 3 on!
@song = Song.newNow what is the HTML code generated by:
<%= form_for @song do |f| %>
<%= f.text_field :title %>
<%= f.submit %>
<% end %>Fill the blanks:
<form action="/songs" method="post">
<input type="text" name="song[title]" value=" ">
<input type="submit" value="Create song">
</form>Imagine that:
@song # => <#Song: id: 18, title: "Hey jude", year: 1968, category: "rock">Now what is the HTML code generated by:
<%= form_for @song do |f| %>
<%= f.text_field :title %>
<%= f.submit %>
<% end %>Fill the blanks:
<form action="/songs/18" method="patch">
<input type="text" name="song[title]" value="Hey jude">
<input type="submit" value="Update song">
</form>- We don't want our visitors to destroy or update reviews, just to create ones.
- We don't want a separate index page to list all reviews or a show page to display each review. Instead, we want to display reviews on the show page of each song, for better UX.
Generate your Review model in the terminal. It should have only a content:string and a song:references (= the foreign key).
rails g model review content:text song:referencesRun the migration
rails db:migrateAdd validation/associations
- Add a validation for the presence of a content
- Add associations between
ReviewandSong
class Song < ApplicationRecord
has_many :reviews
endclass Review < ApplicationRecord
belongs_to :song
validates :content, presence: :true
endGenerate the reviews controller
rails g controller reviewsAdd the necessary routes (donβt forget we donβt want the 7 CRUD actions for reviews)
# config/routes.rb
resources :songs do
resources :reviews, only: [:new, :create]
endNow code your controller:
class ReviewsController < ApplicationController
before_action :set_song
def new
@review = Review.new
end
def create
@review = Review.new(review_params)
@review.song = @song
if @review.save
redirect_to song_path(@song)
else
render 'new'
end
end
private
def set_song
@song = Song.find(params[:song_id])
end
def review_params
params.require(:review).permit(:content)
end
endAdd a songβs reviews on its show page:
<h1><%= @song.title %></h1>
<p><%= @song.year %></p>
<p><%= @song.category %></p>
<h2>Here are the reviews for this song:</h2>
<ul>
<% @song.reviews.each do |review| %>
<li><%= review.content %></li>
<% end %>
</ul>