플랫코인
이 앱은 API를 통해 지속적으로 코인 가격을 가져옵니다. 이전 프로젝트의 코드를 재사용하고 있습니다.
Note: Before even sketching an app you should first research the right API, play around and see what data can you get from it. In my case I used CoinGecko.
Sinatra Activerecord 설정: 가장 중요한 세 가지 보석인 activerecord, sinatra-activerecord 및 rake를 추가해야 합니다.
Gemfile
source 'http://rubygems.org'
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'sinatra'
gem 'activerecord', '~> 6.0.0', :require => 'active_record'
gem 'sinatra-activerecord', :require => 'sinatra/activerecord'
gem 'rake'
gem 'require_all'
gem 'sqlite3'
gem 'thin'
gem 'shotgun'
gem 'pry'
gem 'bcrypt'
gem "tux"
gem 'net-http'
gem 'open-uri'
gem 'json'
gem 'tty-prompt'
group :test do
gem 'capybara'
gem 'rack-test'
gem 'database_cleaner'
end
데이터베이스에 대한 연결 설정:
environment.rb
ENV['SINATRA_ENV'] ||= "development"
require 'net/http'
require 'open-uri'
require 'json'
require 'tty-prompt'
require 'bundler/setup'
Bundler.require(:default, ENV['SINATRA_ENV'])
ActiveRecord::Base.establish_connection(ENV['SINATRA_ENV'].to_sym)
require_all 'app'
database.yml
default: &default
adapter: 'sqlite3'
database: 'db/development.sqlite'
development:
<<: *default
test:
<<: *default
database: 'db/test.sqlite'
config.ru
require './config/environment'
if ActiveRecord::Base.connection.migration_context.needs_migration?
raise 'Migrations are pending. Run `rake db:migrate` to resolve the issue.'
end
use Rack::MethodOverride
run ApplicationController
use UsersController
use TradesController
Rake는 신속하게 파일을 만들고 자동화된 작업을 설정할 수 있는 기능을 제공합니다.
Rakefile
ENV["SINATRA_ENV"] ||= "development"
require_relative './config/environment'
require 'sinatra/activerecord/rake'
users
용 테이블과 trades
용 테이블 두 개를 만들어야 했습니다. 마이그레이션을 실행한 후 내 스키마는 다음과 같습니다.schema.rb
ActiveRecord::Schema.define(version: 2021_03_22_162004) do
create_table "trades", force: :cascade do |t|
t.text "coin_name"
t.decimal "current_price"
t.integer "quantity"
t.integer "user_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.text "email"
t.string "password_digest"
t.decimal "balance"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
모델:
나의 주된 어려움은 올바른 모델을 정의하는 것이었습니다. 사용자의 FlatCoin 잔액, 거래 및 포트폴리오 가치를 어떻게 추적할 수 있습니까? 사용자와 거래를 데이터베이스에 확실히 저장하려면 필요하다는 것을 알고 있었지만 암호 화폐 가치는 어떻습니까? Cryptocurrency 값은 밀리초마다 변동하므로 데이터베이스에서 매번 가격을 저장하고 계속 업데이트하는 것이 이치에 맞지 않습니다. 대신 현재 가격이 필요할 때마다 API 호출을 할 수 있습니다.
api.rb
및 cryptocurrency.rb
는 이전 프로젝트의 사본일 뿐입니다.user.rb
class User < ActiveRecord::Base
has_many :trades
validates_uniqueness_of :email
validates_presence_of :first_name, :last_name, :email
has_secure_password
end
trade.rb
class Trade < ActiveRecord::Base
belongs_to :user
end
견해:
layout.erb
는 앱의 기본 레이아웃을 생성하고 index.erb
는 랜딩 페이지입니다.사용자 하위 폴더는
balance.erb
, login.erb
, logout.erb
및 signup.erb
를 처리합니다.거래 하위 폴더 핸들
all.erb
, confirmation.erb
, edit.erb
, leaderboard.erb
, new.erb
, pick.erb
, rejected.erb
및 sell.erb
.GitHub에서 코드를 확인할 수 있습니다!
컨트롤러:
helpers
에서 application_controller.rb
를 정의하면 logged_in?
를 사용하여 앱에서 로직을 작동할 수 있습니다. 이 프로젝트에서 작업할 때 좋은 점은 tux
를 사용하여 내 데이터베이스를 테스트하고 shotgun
를 실행하여 내 앱을 실시간으로 테스트할 수 있다는 것입니다.application_controller.rb
require './config/environment'
class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views'
enable :sessions
set :session_secret, "aYxiNrafm3ScE4xfa91z2azkuUGJ720y"
end
get '/' do
erb :index
end
helpers do
def logged_in?
!!current_user
end
def current_user
@current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end
end
end
trades_controller.rb
class TradesController < ApplicationController
get '/trade' do
if logged_in?
erb :'trades/pick'
else
redirect to '/'
end
end
post '/trade/new_trade' do
@coin_id = params[:coin_id]
redirect to "/trade/#{@coin_id}"
end
get '/trade/:id' do
if logged_in?
Api.new.get_top_20_cryptocurrencies
@coin = Cryptocurrency.find_by_id(params[:id])
if @coin != nil
erb :'trades/new'
else
redirect to '/'
end
else
redirect to '/'
end
end
post '/trade/status' do
if params[:quantity].to_i > 0
@trade = current_user.trades.build(coin_name: params[:coin_name], current_price: params[:current_price], quantity: params[:quantity])
@new_balance = current_user.balance - (params[:quantity].to_i*params[:current_price].to_f)
if @new_balance > 0
current_user.update(balance: @new_balance)
@trade.save
erb :'trades/confirmation'
else
erb :'trades/rejected'
end
else
redirect to '/'
end
end
get '/trades' do
if logged_in?
@trades = Trade.all
erb :'trades/all'
else
redirect to '/'
end
end
get '/trades/edit/:id' do
if logged_in?
@trade = Trade.find_by_id(params[:id])
if @trade && @trade.user == current_user
erb :'trades/edit'
else
redirect to '/users/balance'
end
else
redirect to '/'
end
end
patch '/trades/edit/:id' do
if logged_in?
@trade = Trade.find_by_id(params[:id])
if @trade && @trade.user == current_user
@trade.update(coin_name: params[:coin_name], current_price: params[:current_price], quantity: params[:quantity])
redirect to '/users/balance'
else
redirect to '/users/balance'
end
else
redirect to '/'
end
end
get '/trades/sell/:id' do
if logged_in?
@trade = Trade.find_by_id(params[:id])
if @trade && @trade.user == current_user
Api.new.get_top_20_cryptocurrencies
coin_name = @trade.coin_name
@updated_coin = Cryptocurrency.find_by_name(coin_name)
@new_balance = current_user.balance + (@trade.quantity.to_i * @updated_coin.current_price.to_f)
erb :'trades/sell'
else
redirect to '/users/balance'
end
else
redirect to '/'
end
end
delete '/trades/sell/:id/delete' do
puts params
if logged_in?
@trade = Trade.find_by_id(params[:id])
if @trade && @trade.user == current_user
current_user.update(balance: params[:new_balance])
@trade.delete
end
redirect to '/users/balance'
else
redirect to '/'
end
end
get '/leaderboard' do
if logged_in?
@users = User.all
erb :'trades/leaderboard'
else
redirect to '/'
end
end
end
users_controller.rb
class UsersController < ApplicationController
get '/users/balance' do
if logged_in?
@trades = current_user.trades.all
erb :'users/balance'
else
redirect to '/'
end
end
get '/signup' do
if !logged_in?
erb :'users/signup', locals: {message: "Please sign up before you sign in"}
else
redirect to '/'
end
end
post '/signup' do
if params[:first_name] == "" || params[:last_name] == "" || params[:email] == "" || params[:password] == ""
redirect to '/signup'
else
@user = User.new(:first_name => params[:first_name], :last_name => params[:last_name], :email => params[:email], :password => params[:password])
@user.balance = 10000 # Free '$10000' for signing up!
@user.save
session[:user_id] = @user.id
redirect to '/'
end
end
get '/login' do
if !logged_in?
erb :'users/login'
else
redirect to '/'
end
end
post '/login' do
user = User.find_by(:email => params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect to '/'
else
redirect to '/signup'
end
end
get '/logout' do
if logged_in?
session.destroy
redirect to '/'
else
redirect to '/'
end
end
end
이 프로젝트는 매우 치열했지만 함께 할 수 있어서 정말 기쁩니다. API, html 및 데이터베이스를 명확하게 이해하는 것은 대화형 앱을 구축하는 데 중요합니다.
내 프로젝트의 짧은 비디오를 확인하십시오.
여기GitHub에서 프로젝트를 확인하세요!
Reference
이 문제에 관하여(플랫코인), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/drivera53/flatcoin-nil텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)