No description or website provided.
Ruby HTML CSS JavaScript
Pull request Compare This branch is 1 commit behind cycorld:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
bin
config
db
lib
log
public
test
tmp
vendor/assets
.gitignore
Gemfile
Gemfile.lock
README.md
Rakefile
config.ru

README.md

jQuery와 Ruby on Rails로 쉽고 빠른 웹 개발하기

Ruby on Rails 의 장점

  1. 코드를 읽기 쉽다. Ruby는 psesudo 코드 같다
  2. SQL문을 작성할 필요가 없다. ORM(Object Relation Mapping)이 너무 편하다
  3. 최소한의 세팅으로 웹 개발에 필요한 온갖 라이브러리를 활용할 수 있다
  4. 시간을 아껴주는 generator가 많다

Ruby on Rails 개발환경 세팅하기

간단한 TODO 리스트 만들기

  1. 프로젝트 생성하기

    $ rails new todo-list
    $ cd todo-list
  2. 서버 실행하기

    $ rails s
  3. Todo 모델 생성하기

    $ rails g model Todo item:string complete:boolean
  4. todos 마이그레이션 파일 수정하기

    db/migrate/xxxxxxxxxxxxxx_create_todos.rb

     class CreateTodos < ActiveRecord::Migration[5.0]
       def change
         create_table :todos do |t|
    -      t.string :item
    -      t.boolean :complete
    +      t.string :item, null: false
    +      t.boolean :complete, default: false
    
           t.timestamps
         end
  5. todos 테이블 생성하기

    $ rake db:migrate
  6. Todos 컨트롤러 생성하기

    $ rails g controller Todos index
  7. CSS 적용하기 : Spoqa 폰트, w3schools

    app/assets/stylesheets/todos.scss

    @import url(//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSans-kr.css);
    * { font-family: 'Spoqa Han Sans', 'Spoqa Han Sans JP', 'Sans-serif'; }
    
    input[type=text], input[type=email], input[type=password] {
        width: 200px;
        padding: 12px 20px;
        margin: 8px 0;
        display: inline-block;
        border: 1px solid #ccc;
        border-radius: 4px;
        box-sizing: border-box;
    }
    
    input[type=submit] {
        background-color: #4CAF50;
        color: white;
        padding: 14px 20px;
        margin: 8px 0;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    }
    
    input[type=submit]:hover {
        background-color: #45a049;
    }
    
    ul {
      padding: 0;
      li {
        list-style: none;
        padding: 6px 0;
      }
    }
    a {
      color: #5484A4;
      text-decoration: none;
    }
    a:hover {
      text-decoration: underline;
    }
  8. 홈페이지 설정하고, todos 라우팅 설정하기

    config/routes.rb 파일 수정

     Rails.application.routes.draw do
    -  get 'todos/index'
    +  root 'todos#index'
    +  resources :todos
    
       # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
     end
  9. Todos 컨트롤러의 index 액션에서 전체 Todo 내용 불러오기

    app/controllers/todos_controller.rb

     class TodosController < ApplicationController
       def index
    +    @todos = Todo.all
       end
     end
  10. View에 전체 리스트 출력하기

    app/views/todos/index.html.erb

    -<h1>Todos#index</h1>
    -<p>Find me in app/views/todos/index.html.erb</p>
    +<h1>TODO 리스트</h1>
    +<ul>
    +  <% @todos.each do |t| %>
    +    <li><%= t.item %></li>
    +  <% end %>
    +</ul>
  11. 새로운 TODO 작성을 위한 Form

    app/views/todos/index.html.erb

     <h1>TODO 리스트</h1>
    +<%= form_tag todos_path do %>
    +  <%= text_field_tag :item, nil, placeholder: "새로운 할 일", autofocus: true %>
    +  <%= submit_tag "추가" %>
    +<% end %>
     <ul>
       <% @todos.each do |t| %>
         <li><%= t.item %></li>
  12. DB에 todo를 저장하기 위한 create 액션 작성하기

    app/controllers/todos_controller.rb

       def index
         @todos = Todo.all
       end
    
    +  def create
    +    Todo.create(item: params[:item], complete: false)
    +    redirect_back fallback_location: root_path
    +  end
     end
  13. 삭제 링크 만들기

    app/views/todos/index.html.erb

     <% end %>
     <ul>
       <% @todos.each do |t| %>
    -    <li><%= t.item %></li>
    +    <li>
    +      <%= t.item %>
    +      <%= link_to '삭제', todo_path(t), method: :delete %>
    +    </li>
       <% end %>
     </ul>
  14. destroy 액션 만들기

    app/controllers/todos_controller.rb

         Todo.create(item: params[:item], complete: false)
         redirect_back fallback_location: root_path
       end
    
    +  def destroy
    +    todo = Todo.find(params[:id])
    +    todo.destroy
    +    redirect_back fallback_location: root_path
    +  end
     end
  15. edit 링크 추가

    app/views/todos/index.html.erb

       <% @todos.each do |t| %>
         <li>
           <%= t.item %>
    +      <%= link_to '수정', edit_todo_path(t) %>
           <%= link_to '삭제', todo_path(t), method: :delete %>
         </li>
       <% end %>
  16. edit 액션 만들기

    app/controllers/todos_controller.rb

         todo.destroy
         redirect_back fallback_location: root_path
       end
    
    +  def edit
    +    @todo = Todo.find(params[:id])
    +  end
     end
  17. app/views/todos/edit.html.erb edit 뷰 생성하기

    <%= form_tag todo_path(@todo), method: :patch do %>
      <%= text_field_tag :item, @todo.item, placeholder: "새로운 할 일", autofocus: true %>
      <%= submit_tag "수정" %>
    <% end %>
  18. update 액션 기능 구현

    app/controllers/todos_controller.rb

       def edit
         @todo = Todo.find(params[:id])
       end
    
    +  def update
    +    todo = Todo.find(params[:id])
    +    todo.update(item: params[:item])
    +    redirect_to root_path
    +  end
     end
  19. 체크 토글 버튼 추가하기 : Font Awesome 사용하여 아이콘 표현

    app/views/todos/index.html.erb

     <ul>
       <% @todos.each do |t| %>
         <li>
    +      <%= link_to toggle_todo_path(t) do %>
    +        <% if t.complete %>
    +          <i class="fa fa-check-square-o" aria-hidden="true"></i>
    +        <% else %>
    +          <i class="fa fa-square-o" aria-hidden="true"></i>
    +        <% end %>
    +      <% end %>
           <%= t.item %>
           <%= link_to '수정', edit_todo_path(t) %>
           <%= link_to '삭제', todo_path(t), method: :delete %>
  20. CDN에서 Font Awesome 불러오기

    app/views/layouts/application.html.erb

         <%= csrf_meta_tags %>
    
         <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    +    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css
         <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
       </head>
  21. toggle 라우트 추가하기

    config/routes.rb

     Rails.application.routes.draw do
       root 'todos#index'
    -  resources :todos
    +  resources :todos do
    +    member do
    +      get 'toggle'
    +    end
    +  end
    
       # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
     end
  22. toggle 액션 기능 구현하기

         todo.update(item: params[:item])
         redirect_to root_path
       end
    
    +  def toggle
    +    todo = Todo.find(params[:id])
    +    todo.complete = !todo.complete
    +    todo.save
    +    redirect_to root_path
    +  end
     end

회원가입, 로그인 등 User 기능 만들기

  1. devise 젬 설치하기

    Gemfile 에 아래 코드 추가

    gem 'devise'
    

    젬 설치 하기

    $ bundle install

    Devise init 하기

    $ rails generate devise:install

    서버 재시작하기

    Ctrl + c 로 서버 종료 후
    $ rails s

    Devise 뷰 생성하기

    $ rails g devise:views

    User 모델 생성하기

    $ rails generate devise User

    users 테이블 생성하기

    $ rake db:migrate
  2. 메뉴 만들기

    app/views/layouts/application.html.erb

       </head>
    
       <body>
    +    <% if user_signed_in? %>
    +      <%= current_user.email %>
    +      <%= link_to '로그아웃', destroy_user_session_path, method: :delete %>
    +    <% else %>
    +      <%= link_to '로그인', new_user_session_path %>
    +      <%= link_to '회원가입', new_user_registration_path %>
    +    <% end %>
    +
    +    <p class="notice"><%= notice %></p>
    +    <p class="alert"><%= alert %></p>
    +
         <%= yield %>
       </body>
     </html>
  3. 로그인한 사용자만 접근 가능하도록 만들기

    app/controllers/todos_controller.rb

     class TodosController < ApplicationController
    +  before_action :authenticate_user!
    
       def index
         @todos = Todo.all
       end
     end
  4. todos 테이블에 user_id (foreign key) 추가하기

    $ rails g migration AddUserToTodos user:references

    todos 테이블에 user_id 컬럼 추가 반영하기

    $ rake db:migrate
  5. Todo 모델과 User 모델 관계 설정하기

    app/models/todo.rb

     class Todo < ApplicationRecord
    +  belongs_to :user
     end

    app/models/user.rb

     class User < ApplicationRecord
       # Include default devise modules. Others available are:
       # :confirmable, :lockable, :timeoutable and :omniauthable
       devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable
    +  has_many :todos
     end
  6. 사용자의 Todo만 보여주기

    app/controllers/todos_controller.rb

       def index
    -    @todos = Todo.all
    +    @todos = current_user.todos
       end
  7. Todo 작성시 사용자 정보 넣기

    app/controllers/todos_controller.rb

       def create
    -    Todo.create(item: params[:item], complete: false)
    +    Todo.create(item: params[:item], complete: false, user: current_user)
         redirect_back fallback_location: root_path
       end
  8. before_action을 이용해 권한 설정하기

    app/controllers/todos_controller.rb

     class TodosController < ApplicationController
       before_action :authenticate_user!
    +  before_action :set_todo, only: [:destroy, :edit, :update, :toggle]
    +  before_action :check_owner, only: [:destroy, :edit, :update, :toggle]
    
       def index
         @todos = current_user.todos
       end
    
       def create
         Todo.create(item: params[:item], complete: false, user: current_user)
         redirect_back fallback_location: root_path
       end
    
       def destroy
    -    todo = Todo.find(params[:id])
    -    todo.destroy
    +    @todo.destroy
         redirect_back fallback_location: root_path
       end
    
       def edit
    -    @todo = Todo.find(params[:id])
       end
    
       def update
    -    todo = Todo.find(params[:id])
    -    todo.update(item: params[:item])
    +    @todo.update(item: params[:item])
         redirect_to root_path
       end
    
       def toggle
         todo = Todo.find(params[:id])
    -    todo.complete = !todo.complete
    -    todo.save
    +    @todo.complete = !todo.complete
    +    @todo.save
         redirect_to root_path
       end
    
    +  private
    +
    +  def set_todo
    +    @todo = Todo.find(params[:id])
    +  end
    +
    +  def check_owner
    +    unless current_user == @todo.user
    +      flash[:alert] = '권한이 없습니다'
    +      return redirect_to root_path
    +    end
    +  end
     end

수정 기능 ajax 로 처리하기

  1. item을 span tag로 감싸기

    app/views/todos/index.html.erb

             <% if t.complete %>
               <i class="fa fa-check-square-o" aria-hidden="true"></i>
             <% else %>
               <i class="fa fa-square-o" aria-hidden="true"></i>
             <% end %>
           <% end %>
    -      <%= t.item %>
    +      <span data-id="<%= t.id %>" class="item"><%= t.item %></span>
           <%= link_to '수정', edit_todo_path(t) %>
           <%= link_to '삭제', todo_path(t), method: :delete %>
         </li>
  2. javascript 코드 작성하기

    app/assets/javascripts/todos.coffeeapp/assets/javascripts/todos.js로 수정하기

    주석을 모두 제거하기

    $(document).on('turbolinks:load', function() {
      $('.item').bind('dblclick', function() {
        $(this).attr('contentEditable', true)
          .keypress(function(e) {
            if (e.which == 13) {
              $.ajax({url: '/todos/' + $(this).data('id'),
                     type: 'patch',
                     data: {item: $(this).text()}});
              return false;
            }
          });
      }).blur(function() {
        $(this).attr('contentEditable', false);
      });
    });
  3. jQuery <=> javascript