It took a week and two days to create a simplified version of the flea market app using Ruby
and JavaScript
.
It is a personal record of the points I stumbled upon and how I got over it.
Flea market apps
Use Ruby on Rails 6.0.0
** Where I was interested **
Column | Type | Options |
---|---|---|
nickname | string | null: false |
string | null: false, unique: true | |
encrypted_password | string | null: false |
first_name | string | null: false |
last_name | string | null: false |
first_name_k | string | null: false |
last_name_k | string | null: false |
birth | date | null: false |
Association has_many :items has_many :order
Column | Type | Options |
---|---|---|
name | string | null: false |
text | text | null: false |
category_id | integer | null: false |
condition_id | integer | null: false |
delivery_fee_id | integer | null: false |
prefecture_id | integer | null: false |
delivery_day_id | integer | null: false |
price | integer | null: false |
user | references | null: false, foreign_key: true |
Association belongs_to :user belongs_to :category_id belongs_to :condition_id belongs_to :delivery_fee_id belongs_to :prefecture_id belongs_to :delivery_day_id has_one :order
Column | Type | Options |
---|---|---|
user | references | null: false, foreign_key: true |
item | references | null: false, foreign_key: true |
Association belongs_to :user belongs_to :item has_one :address
Column | Type | Options |
---|---|---|
postal_cord | string | null: false |
prefecture_id | integer | null: false |
city | string | null: false |
house_number | string | null: false |
building | string | |
phone_number | string | null: false |
buy_record | references | null: false, foreign_key: true |
Association belongs_to :order belongs_to :prefecture_id
ED diagram
** Rough flow **
gem'devise'
application_controller.rb
, specify parameters so that values other than email
and password
are saved in the DB** Where I stumbled **
password
with both half-width alphanumeric characters required (I have never tampered with the validation of email
and password
)email
with @
email
** Solution **
Until I created this flea market app, I was upset because I had hardly tampered with the validation of email
and password
of devise
. By default, it seems that password
can be registered with just numbers. I had to validate email
myself because I would remove the entire validation that comes with devise
.
The following are (1) remove the default validation of devise
(2) regular expression that applies alphanumeric character required validation to password
(3) convenient for applying multiple validations with_options
(4) necessary to match the input twice. I'm writing about validation.
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
#↑ Delete
# 'password'Regular expression to validate
# '.freeze'Is'PASSEOWD_REGEX'Method to prevent rewriting
PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze
# 'with_options'Allows you to add multiple options to validation at once
# 'confirmation'→':password'When':password_Does the value received in confirmation match?
with_options presence: true, format: { with: PASSWORD_REGEX, message:'Please include both letters and numbers in' }, length: { minimum: 6 }, confirmation: true do
validates :password
end
Reference site [Rails] Customize devise validation Active Record Validation (https://railsguides.jp/active_record_validations.html#confirmation)
This is a validation to prevent the email
from being registered twice.
uniqueness
is applicable. case_sensitive: false
is case insensitive.
user.rb
# 'uniqueness'→'email'Validate the uniqueness of
#With regular expression'@'Instructed to include
with_options presence: true, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, message: '@Please enter including' }, uniqueness: { case_sensitive: false } do
validates :email
end
Reference site [Rails] Email Address Validation [Rails] Verification of uniqueness of email address [Rails Tutorial Chapter 6 Summary] instance method Object#freeze
Until now, I had only used Faker
to create dummy data, so I was confused as to" What is the name of the kanji? And also Frigana? ", But when I searched, I found the perfect library. ..
spec/factories/users.rb
FactoryBot.define do
factory :user do
#Omission
first_name {Gimei.first.kanji}
last_name {Gimei.last.kanji}
first_name_k {Gimei.first.katakana}
last_name_k {Gimei.last.katakana}
birth {Faker::Date.between(from: '1990-01-01', to:'2020-12-08')}
end
end
Thank you very much for making Gimei ... Reference site [Rails] Generate Japanese dummy data with gem ‘gimei’ [Japanese Faker] About the gem "gimei"
This is a correction that was returned after requesting a review.
spec/factories/users.rb
factory :user do
#Omission
password = Faker::Internet.password(min_length: 6)
If left unchecked,'Faker' may generate a password with only numbers, which can lead to errors.
spec/factories/users.rb
password = '1a' + Faker::Internet.password(min_length: 6)
I fixed it to.
** Rough flow **
gem'active_hash'`` gem'mini_magick'
gem'image_processing'
** Where I stumbled **
JavaScript
to calculate the amount on the screen: price
column** Solution **
I want to make this
javascript/card.js
function price() {
const priceInput = document.getElementById("item-price");
priceInput.addEventListener("input", () => {
const inputValue = priceInput.value;
const addTaxDom = document.getElementById("add-tax-price");
const profit = document.getElementById("profit");
addTaxDom.innerHTML = Math.floor(inputValue * 0.1);
profit.innerHTML = Math.floor(inputValue - inputValue * 0.1);
})
}
window.addEventListener('load', price)
First, getElementById ("item-price")
gets the element to enter the amount, and priceInput.value
gets the value entered. Using this inputValue
, the value calculated in () of Math.floor
will be rounded off to the nearest whole number, and the commission and profit amount of 10% of the entered amount will be displayed on the screen. I can put it out.
Reference site
Active engineers explain how to use the Math.floor method of JavaScript [for beginners]
Since the amount that can be set by the user is ¥ 300 to ¥ 9,999,999, it is necessary to set the validation that only this range can be entered.
item.rb
with_options presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 300, less_than_or_equal_to: 9999999 } do
validates :price
end
You have now set a range of values for validation. Reference site Use numericity to verify that only numbers are used for attributes
I proceeded smoothly here. Be careful because DRY's law tends to be missed.
Here, we worked on two major new things. ① Introduction of open API ② Form object pattern is.
When the application implements the purchase function, it is not recommended to receive the card information directly from the user and process the payment because of the large amount of paperwork and the difficulty of ensuring certain security standards.
Therefore, we will implement it via a credit card payment agency service. This time I used PAY.JP
.
As a processing flow ① The user inputs the card information on the card input screen ② ① is tokenized and the token is sent to the server side To do.
In addition, in this application, one form is used for (1) tokens, (2) purchase information (id
record of the purchased user and id
record of the purchased product), and (3) delivery destination information, three different tables (or not). Must be saved at once. Until now, I have only created an application that supports only one table for one form. The Form object pattern is used here.
As a flow
(1) Create a new file directly under the model directory, define a class, and set ActiveModel :: Model
to inclede
.
② Use attr_accessor
to use all the attributes used in this form.
③ Describe the validation process
④ Describe the process of saving the received data
It's a feeling.
model/user_order.rb
class UserOrder
include ActiveModel::Model
attr_accessor :token, :postal_code, :prefecture_id, :city, :house_number, :building, :phone_number, :item_id, :user_id
with_options presence: true do
validates :token
validates :postal_code, format: { with: /\A\d{3}[-]\d{4}\z/, message: "is invalid. Include hyphen(-)"}
validates :city, format: { with: /\A[Ah-Hmm-One-龥]/, message: "is invalid. Input full-width characters."}
validates :house_number
validates :phone_number, format: { with: /\A\d{10,11}\z/, message: "is invalid."}
validates :user_id
validates :item_id
end
validates :prefecture_id, numericality: { other_than: 1, message: "can't be blank" }
def save
order = Order.create(user_id: user_id, item_id: item_id)
Address.create(postal_code: postal_code, prefecture_id: prefecture_id, city: city, house_number: house_number, building: building, phone_number: phone_number, order_id: order.id)
end
end
Now you can handle data from multiple tables at once in one form.
Also, since attr_accessor
is used when you want to handle attributes other than the column name of the table that originally corresponds to the (?) Model, you can also handle the value of: token
that has no column in the table. This is because it automatically does a getter
that allows you to get the value and a setter
that allows you to update the value, but I'm going to go a little deeper next time.
Another thing I stumbled upon was the place to put the letters Sold Out
after purchasing.
Here, describe the conditional branch "Does the data of order
exist? "In the view file in the data of each product.
views/order/index.html
<% if item.order.present? %>
<div class='sold-out'>
<span>Sold Out!!</span>
</div>
<% end %>
Reference site Let's master nil? Blank? Empty? Present? In Rails
The rest is Basic authentication & deployment and the end. To be honest, I was confused because there were many things nice to meet you, but I managed to achieve the basic implementation. I will make an original from now on, so I will not be able to see the goal further, but I will do my best. From now on, I would like to write diligently to organize information.