3 minute read

  1. form_for

If you do form for, instead of httml source,
techinally it works same as like HTML source
but it do connect to next page, and set method stuff for us

If form_for(@resto)
has id X ===> next: create / method: push
has id O ===> next: update / method: patch

<!-- app/views/restaurants/_form.html.erb -->
<%= form_for(@restaurant) do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  <%= f.label :address %>
  <%= f.text_field :address %>
  <%= f.submit %>
<% end %>


short cut for form_for for same pages

<!-- app/views/restaurants/new.html.erb -->
<%= render 'form' %>
<!-- app/views/restaurants/edit.html.erb -->
<%= render 'form', restaurant: @restaurant %>
  1. What rails do for me?

1) rails new APP_NAME
2) rails generate model Restaurant name:string address:strinng
3) rails db:migrate
4) Edit details of model
5) rails db:migrate
6) rails generate controller Restarant method_name method_name method_name

rails db:drop     # Drops the database (lose all your data!)
rails db:create   # Creates the database with an empty schema
rails db:migrate  # Runs pending migrations on the database schema
rails db:seed     # Runs seeds.rb file
rails db:rollback # Revert the last migration
rails db:reset    # Drops database + replays all migration + runs seed

3.If I need edit Migration
put this line in Terminal

rails generate migration AddAddressToRestaurants address:string
  1. About CRUD
    Make it 7 CRUD routes for me
Rails.application.routes.draw do
  resources :restaurants
end

In case of only need specific pages

Rails.application.routes.draw do
  resources :restaurants, only: [:index, :show]
end
  1. UPDATE
    Because any user can access or edit data form in HTML, make ‘params’ locked.
    Make the params.require(:model).permit(:method) on the last line,
    and mark it as to private
class RestaurantsController < ApplicationController
  def update
    restaurant = Restaurant.find(params[:id])
    restaurant.update(restaurant_params)
    redirect_to restaurant_path(restaurant)
  end

  [...]

  private

  def restaurant_params
    params.require(:restaurant).permit(:name, :address, :stars)
  end
end
  1. before action filter

When we need exact same line in Method,
using before action like below.

In this case

# app/controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
  def show
    @restaurant = Restaurant.find(params[:id])
    # ...
  end
  def edit
    @restaurant = Restaurant.find(params[:id])
    # ...
  end
  def update
    @restaurant = Restaurant.find(params[:id])
    # ...
  end
  def destroy
    @restaurant = Restaurant.find(params[:id])
    # ...
  end
end


1) Make set_restaurant Method in Private
2) Add it right after the class line

# app/controllers/restaurants_controller.rb
class RestaurantsController < ApplicationController
  before_action :set_restaurant, only: [:show, :edit, :update, :destroy]

  def show
    # ...
  end
  def edit
    # ...  
  end
  def update
    # ...
  end
  def destroy
    # ...
  end

  private

  def set_restaurant
    @restaurant = Restaurant.find(params[:id])
  end
end

+++) sample

  1. routes
Rails.application.routes.draw do

  # CREATE
  get 'tasks/new', to: "tasks#new", as: "new_task"
  post 'tasks', to: "tasks#create", as: "tasks"

  # READ
  get 'tasks/:id', to: "tasks#show", as: "task"
  get 'tasks', to: "tasks#index"

  # UPDATE
  get 'tasks/:id/edit', to: "tasks#edit", as: "edit_task"
  patch 'tasks/:id', to: "tasks#update"

  # DELETE
  delete 'tasks/:id', to: "tasks#destroy"

end

  1. Controller
class TasksController < ApplicationController

  before_action :find_id, only: [:show, :edit, :update, :destroy]

  # CREATE
  def new
    @task = Task.new # This is for rendering form_for
  end

  def create
    @task = Task.new(user_params)
    @task.save
    redirect_to task_path(@task)
  end

  # READ
  def show
    # @task = Task.find(params[:id])
  end

  def index
    @tasks = Task.all
  end

  # UPDATE
  def edit
    # @task = Task.find(params[:id])
  end

  def update
    # @task = Task.find(params[:id])
    @task.update(user_params)
    redirect_to task_path(@task)
  end


  # DELETE
  def destroy
    # @task = Task.find(params[:id])
    @task.destroy
    redirect_to tasks_path # index
  end

  private

  def find_id
    @task = Task.find(params[:id])
  end

  # returns a hash of cat attributes that are safe
  def user_params
    params.require(:task).permit(:title, :details, :completed)
  end

end
  1. View_ show
<h1>Tasks#show</h1>


<div class="card">

  <h3><%= @task.details %></h3>

    <% if @task.completed %>
      <input type="checkbox" checked> This task is finished<br>
    <% else %>
      <input type="checkbox"> This task needs to be finished<br>
    <% end %>

</div>

<%= link_to "⬅️", tasks_path %>
<%= link_to "⚙️", edit_task_path %>
  1. HTML_index

<h1>MY TASK</h1>
<div class="card">
  <ul>
    <% @tasks.each do |task| %>
      <li>
        <input type ="checkbox" <%= "checked" if task.completed %>>
        <%= link_to task.title, task_path(task) %>
        <%= link_to "🔪", task_path(task), method: :delete, data: { confirm: "You really want?"} %>
      </li>
    <% end %>
  </ul>
</div>
<%= link_to "➕", new_task_path %>

Categories:

Updated: