[Ruby] Make a family todo list with Sinatra

3 minute read

Create a family todo list with #Sinatra

It was created by trying to make one app with Sinatra. Even so, I refer to here for the function as the base.

Introduction to Sinatra (17 times)-Dot install for programming


This time, we will add a function to make it a todo list that can be used by the family. The following four main functions are added.

  • Display of post time
  • Select box to select users
  • User-friendly todo display
  • New user registration

I think it will be a good subject as a step-up from the introduction to sinatra. First of all, it is the screen of the completed application. view90%.png

Below is the explanation of the code.

Display post time

Read Date class into rb file.

tlist.rb


require date

Created_at is added to the table created by SQL file (record generation time is automatically acquired).

table.sql


create table todos
(
  id integer PRIMARY key,
  users_id integer,
  body text,
  created_at
);

Added a block that displays the post time in the block that sequentially displays the body element with each method for @todos of the instance variable. Change it to Time class by To_time method and format it easily by strftimeme method.

index.erb


<div class=“time”>
  <%= todo.created_at.to_time.strftime(%Y/%m/%d %H:%M:%S)%>
  <span class=“delete delete_todo>[x]</span>
</div>

Install a select box to specify the user

Create users table in SQL file.

table.sql


create table users
(
  id integer primary key,
  userName text
);

Store table information in Users class using ActiveRecord::Base method.

tlist.rb


class Users <ActiveRecord::Base
  validates :userName, presence: true
end

Pass the Users class to the instance variable.

tlist.rb


get / do
  @title = To do list
  @todos = Todos.all
  @users = Users.all
  erb :index
end

By allowing each method to display the values in the select box sequentially, the user can be selected in the select box.

index.erb


<select name=“users_id”>
  <% @users.each do |user|%>
    <option value=<%= user.id%>><%= user.userName%></option>
  <% end %>
</select>

Display todo item corresponding to user

I didn’t know how to implement one-to-many table, so I added the result when id matches in if statement. The value sent by the previous select is the id of the users table, and it is set so that it is passed to the users_id of the todos table.


Add the data sent by post to the todos table.

tlist.rb


post /create_todo do
  Todos.create(body: params[:body],users_id: params[:users_id])
  redirect to(/)
end


Show todo list for each user. Display users in order at @users.esch If the id of the given users table and the users_id of the todos table match, the todo list will be displayed.

index.erb


  <% @users.each do |user| %>
    <div class=“user_box” data-user_id = <%=user.id%> data-token = <%= Rack::Csrf.csrf_token(env)%>>
        <div class=“user_name”>
          <%= Rack::Utils.escape_html(user.userName)%>
          <span class=“delete delete_user>[x]</span>
        </div>
        <ul>
          <% @todos.each do |todo|%>
            <%if user.id == todo.users_id%>
              <li data-id = <%= todo.id%> data-token = <%= Rack::Csrf.csrf_token(env)%>>
                <div class=“todo_body”>
                  <%= Rack::Utils.escape_html(todo.body)%>
                </div>
              </li>
          <% end%>
        </ul>
      <% end %>
    </div>
  <% end %>

New user registration function

Create a form similar to the input form of Todo list and set it to return the entered value as userName.

index.erb


<div class=“user_form”>
  <form action=“/create_user” method = “post”>
    <%= Rack::Csrf.csrf_tag(env)%>
    <span>New username:</span>
    <input type=“text” name=“userName” class=“user_input_box”>
    <input type=“submit” value=“new registration class = ‘btn btn_user>
  </form>
</div>

Generate data in users table.

tlist.rb


post /create_user do
  Users.create(userName: params[:userName])
  redirect to(/)
end

Most of the above is completed. Other token processing and user deletion functions are omitted here. The productions are listed on github, so please look there.

Other notes

About Csrf (forced request) measures *(CSRF: Cross-site Request Forgery) It is provided to prevent the request from being sent against the user’s intention. You can check whether the request was sent from the legitimate page on the request destination page. As a process, a token is placed in the input data with a hidden element, and the request destination confirms whether the token is formal.

Reference: Hyoko engineer summarized CSRF countermeasures (will be updated from time to time)|Chrono Drive