Skip to content

Instantly share code, notes, and snippets.

@juliends
Last active May 21, 2018 10:54
Show Gist options
  • Save juliends/7818aa66317e5c961cce3a46419b04b1 to your computer and use it in GitHub Desktop.
Save juliends/7818aa66317e5c961cce3a46419b04b1 to your computer and use it in GitHub Desktop.
Quizz Rails

Quizz 4 - Rails

Q1 - How do you create a Rails app?

rails new NOM_DE_L_APP
rails new NOM_DE_L_APP --webpack
rails new NOM_DE_L_APP --database=postgres

Q2 - How do you start coding a Rails project? Give the right sequence.

  1. Coding the views?
  2. Coding the controllers?
  3. Coding the models?

πŸ‘‰ 3 - 2 - 1

Q3 - How do you generate a Song model with a title and a year ?

rails generate model song title year:integer

What are the 2 created files?

πŸ‘‰ The migration and the model.

What is the rails command you should type then?

rails db:migrate

Q4 - How do you add a category (ex: "rock" , "electro" , etc..) to your songs table using the correct Rails generator?

rails g migration AddCategoryToSongs category

What is the created file?

πŸ‘‰ a new migration

What is the rails command you should type again?

rails db:migrate

Q5 - Add a validation on the presence of a song title & crash-test your model in the console

# models/song.rb
class Song < ApplicationRecord # Add the validation
  validates :title, presence: :true
end

Now crash-test your model:

song = Song.new
song.valid?

song.errors.messages

song.title = "hey jude"
song.save

Q6 - What is the Rails flow you need to follow again and again? Give the correct order

  1. The Router is routing the HTTP request to "controller#action"
  2. The action is getting data from models
  3. Everything starts with an HTTP Request
  4. The action is rendering the view

πŸ‘‰ 3 - 1 - 2 - 4

Q7 - What are the 4 different parts inside an HTTP request

  1. Verb
  2. Url
  3. Header
  4. Body

Q8 - Are the HTTP requests in the following 2 routes the same? Why?

# config/routes.rb
get "/songs" => "songs#index"
post "/songs" => "songs#create"

πŸ‘‰ No, verbs are differents.

Q9 - What's the difference between a GET and a POST request?

πŸ‘‰ GET requests have no body. Data can only be sent via the url's query string (visible to users)

Q10 - Complete the controller code using the correct params key?

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
end

Q11 - Complete the controller code using the correct params key?

HTTP 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

Q12 - What are the 7 CRUD routes generated by the resources method in Rails?

# 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"

Q13 - How do you print your routes and their URL prefix helpers?

rails routes

Q14 - How do you generate a controller for your songs?

rails generate controller songs

Q15 - Implement the Read actions in your songs controller?

class SongsController < ApplicationController
  def index
    @songs = Song.all
  end

  def show
    @song = Song.find(params[:id])
  end
end

Q16 - 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

Q17 - Why do we have to filter parameters using "strong params" in the controller?

πŸ‘‰ 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!

Q18 - Hard question: What is the HTML generated?

@song = Song.new

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" method="post">
  <input type="text" name="song[title]" value="  ">
  <input type="submit" value="Create song">
</form>

Q19 - Hard question: What is the HTML generated?

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>

Adding a 2nd model

Q20 - Now you want to add reviews to your app. Here are some constraints

  • 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.

Step #1: Model

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:references

Run the migration

rails db:migrate

Add validation/associations

  • Add a validation for the presence of a content
  • Add associations between Review and Song
class Song < ApplicationRecord
  has_many :reviews
end
class Review < ApplicationRecord
  belongs_to :song
  validates :content, presence: :true
end

Step #2: Routing/Controller

Generate the reviews controller

rails g controller reviews

Add 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]
end

Now 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
end

Step #3: Views

Add 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment