尝试用rails发送邮件、了解rails视图和模板引擎、了解并上手rails模型查询和关联的一些相关操作
This commit is contained in:
parent
1b53a06e65
commit
121a18dbd0
|
|
@ -55,19 +55,34 @@
|
|||
<orderEntry type="library" scope="PROVIDED" name="commonjs (v0.2.7, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.10, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="crass (v1.0.6, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="database_cleaner (v2.0.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="database_cleaner-active_record (v2.0.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="database_cleaner-core (v2.0.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="devise (v4.8.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.5.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="erubi (v1.10.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="erubis (v2.7.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="execjs (v2.8.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="factory_girl (v4.9.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="factory_girl_rails (v4.9.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="ffi (v1.15.5, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="globalid (v0.4.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="haml (v5.2.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="haml-rails (v2.0.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="html2haml (v2.2.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="io-like (v0.3.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="jbuilder (v2.11.5, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="jquery-rails (v4.4.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="kaminari (v1.1.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="kaminari-actionview (v1.1.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="kaminari-activerecord (v1.1.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="kaminari-core (v1.1.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="less (v2.6.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="less-rails (v5.0.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="libv8 (v3.16.14.19, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="liquid (v4.0.3, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="liquid-rails (v0.2.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="listen (v3.1.5, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.18.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="mail (v2.7.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
|
|
@ -96,21 +111,24 @@
|
|||
<orderEntry type="library" scope="PROVIDED" name="ref (v2.0.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="regexp_parser (v1.8.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="responders (v2.4.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.9.3, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.9.4, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.9.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-rails (v3.9.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.9.4, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.11.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.11.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.11.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-rails (v5.1.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.11.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="ruby_dep (v1.5.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="ruby_parser (v3.19.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="rubyzip (v1.3.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sass (v3.7.4, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sass-listen (v4.0.0, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sass-rails (v5.0.7, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="selenium-webdriver (v3.142.7, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sexp_processor (v4.16.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="spring (v2.0.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="spring-watcher-listen (v2.0.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sprockets (v3.7.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="temple (v0.8.2, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="therubyracer (v0.12.3, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="thor (v1.2.1, rbenv: 2.3.7) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.6, rbenv: 2.3.7) [gem]" level="application" />
|
||||
|
|
@ -154,12 +172,22 @@
|
|||
<option value="devise:controllers" />
|
||||
<option value="devise:install" />
|
||||
<option value="devise:views" />
|
||||
<option value="erb:controller" />
|
||||
<option value="erb:mailer" />
|
||||
<option value="erb:scaffold" />
|
||||
<option value="factory_girl:model" />
|
||||
<option value="generator" />
|
||||
<option value="haml:application_layout" />
|
||||
<option value="haml:controller" />
|
||||
<option value="haml:mailer" />
|
||||
<option value="haml:scaffold" />
|
||||
<option value="helper" />
|
||||
<option value="integration_test" />
|
||||
<option value="jbuilder" />
|
||||
<option value="job" />
|
||||
<option value="js:assets" />
|
||||
<option value="kaminari:config" />
|
||||
<option value="kaminari:views" />
|
||||
<option value="less:assets" />
|
||||
<option value="less:scaffold" />
|
||||
<option value="mailer" />
|
||||
|
|
@ -169,16 +197,17 @@
|
|||
<option value="resource" />
|
||||
<option value="responders:install" />
|
||||
<option value="responders_controller" />
|
||||
<option value="rspec:channel" />
|
||||
<option value="rspec:controller" />
|
||||
<option value="rspec:feature" />
|
||||
<option value="rspec:generators" />
|
||||
<option value="rspec:generator" />
|
||||
<option value="rspec:helper" />
|
||||
<option value="rspec:install" />
|
||||
<option value="rspec:integration" />
|
||||
<option value="rspec:job" />
|
||||
<option value="rspec:mailbox" />
|
||||
<option value="rspec:mailer" />
|
||||
<option value="rspec:model" />
|
||||
<option value="rspec:observer" />
|
||||
<option value="rspec:request" />
|
||||
<option value="rspec:scaffold" />
|
||||
<option value="rspec:system" />
|
||||
|
|
@ -220,12 +249,22 @@
|
|||
<option value="devise:controllers" />
|
||||
<option value="devise:install" />
|
||||
<option value="devise:views" />
|
||||
<option value="erb:controller" />
|
||||
<option value="erb:mailer" />
|
||||
<option value="erb:scaffold" />
|
||||
<option value="factory_girl:model" />
|
||||
<option value="generator" />
|
||||
<option value="haml:application_layout" />
|
||||
<option value="haml:controller" />
|
||||
<option value="haml:mailer" />
|
||||
<option value="haml:scaffold" />
|
||||
<option value="helper" />
|
||||
<option value="integration_test" />
|
||||
<option value="jbuilder" />
|
||||
<option value="job" />
|
||||
<option value="js:assets" />
|
||||
<option value="kaminari:config" />
|
||||
<option value="kaminari:views" />
|
||||
<option value="less:assets" />
|
||||
<option value="less:scaffold" />
|
||||
<option value="mailer" />
|
||||
|
|
@ -235,16 +274,17 @@
|
|||
<option value="resource" />
|
||||
<option value="responders:install" />
|
||||
<option value="responders_controller" />
|
||||
<option value="rspec:channel" />
|
||||
<option value="rspec:controller" />
|
||||
<option value="rspec:feature" />
|
||||
<option value="rspec:generators" />
|
||||
<option value="rspec:generator" />
|
||||
<option value="rspec:helper" />
|
||||
<option value="rspec:install" />
|
||||
<option value="rspec:integration" />
|
||||
<option value="rspec:job" />
|
||||
<option value="rspec:mailbox" />
|
||||
<option value="rspec:mailer" />
|
||||
<option value="rspec:model" />
|
||||
<option value="rspec:observer" />
|
||||
<option value="rspec:request" />
|
||||
<option value="rspec:scaffold" />
|
||||
<option value="rspec:system" />
|
||||
|
|
@ -404,6 +444,11 @@
|
|||
<RakeTaskImpl description="Toggle development mode caching on/off" fullCommand="dev:cache" id="cache" />
|
||||
</subtasks>
|
||||
</RakeTaskImpl>
|
||||
<RakeTaskImpl id="haml">
|
||||
<subtasks>
|
||||
<RakeTaskImpl description="Convert html.erb to html.haml each file in app/views" fullCommand="haml:erb2haml" id="erb2haml" />
|
||||
</subtasks>
|
||||
</RakeTaskImpl>
|
||||
<RakeTaskImpl description="Print out all defined initializers in the order they are invoked by Rails" fullCommand="initializers" id="initializers" />
|
||||
<RakeTaskImpl id="log">
|
||||
<subtasks>
|
||||
|
|
|
|||
10
Gemfile
10
Gemfile
|
|
@ -37,6 +37,12 @@ gem "devise"
|
|||
|
||||
# JQuery
|
||||
gem "jquery-rails"
|
||||
|
||||
# Haml模板引擎相关
|
||||
gem "haml"
|
||||
gem "html2haml"
|
||||
gem "haml-rails"
|
||||
gem 'liquid-rails'
|
||||
# Use Redis adapter to run Action Cable in production
|
||||
# gem 'redis', '~> 4.0'
|
||||
# Use ActiveModel has_secure_password
|
||||
|
|
@ -54,7 +60,9 @@ gem 'bootsnap', '>= 1.1.0', require: false
|
|||
group :development, :test do
|
||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
||||
gem 'rspec-rails', '~> 3.0'
|
||||
gem 'rspec-rails', '~> 5.1.2'
|
||||
gem "factory_bot"
|
||||
gem "database_cleaner"
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
|
|
|||
82
Gemfile.lock
82
Gemfile.lock
|
|
@ -75,6 +75,12 @@ GEM
|
|||
commonjs (0.2.7)
|
||||
concurrent-ruby (1.1.10)
|
||||
crass (1.0.6)
|
||||
database_cleaner (2.0.1)
|
||||
database_cleaner-active_record (~> 2.0.0)
|
||||
database_cleaner-active_record (2.0.1)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
devise (4.8.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
|
|
@ -83,10 +89,27 @@ GEM
|
|||
warden (~> 1.2.3)
|
||||
diff-lcs (1.5.0)
|
||||
erubi (1.10.0)
|
||||
erubis (2.7.0)
|
||||
execjs (2.8.1)
|
||||
factory_bot (5.2.0)
|
||||
activesupport (>= 4.2.0)
|
||||
ffi (1.15.5)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
haml (5.2.2)
|
||||
temple (>= 0.8.0)
|
||||
tilt
|
||||
haml-rails (2.0.1)
|
||||
actionpack (>= 5.1)
|
||||
activesupport (>= 5.1)
|
||||
haml (>= 4.0.6, < 6.0)
|
||||
html2haml (>= 1.0.1)
|
||||
railties (>= 5.1)
|
||||
html2haml (2.2.0)
|
||||
erubis (~> 2.7.0)
|
||||
haml (>= 4.0, < 6)
|
||||
nokogiri (>= 1.6.0)
|
||||
ruby_parser (~> 3.5)
|
||||
i18n (1.10.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-like (0.3.1)
|
||||
|
|
@ -97,6 +120,18 @@ GEM
|
|||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
kaminari (1.1.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
kaminari-activerecord (= 1.1.1)
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-actionview (1.1.1)
|
||||
actionview
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-activerecord (1.1.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-core (1.1.1)
|
||||
less (2.6.0)
|
||||
commonjs (~> 0.2.7)
|
||||
less-rails (5.0.0)
|
||||
|
|
@ -104,6 +139,11 @@ GEM
|
|||
less (~> 2.6.0)
|
||||
sprockets (~> 3.0)
|
||||
libv8 (3.16.14.19-x86_64-linux)
|
||||
liquid (4.0.3)
|
||||
liquid-rails (0.2.0)
|
||||
kaminari (~> 1.1.1)
|
||||
liquid (~> 4.0.0)
|
||||
rails (>= 5.0.6)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
|
|
@ -166,24 +206,26 @@ GEM
|
|||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
railties (>= 4.2.0, < 6.0)
|
||||
rspec-core (3.9.3)
|
||||
rspec-support (~> 3.9.3)
|
||||
rspec-expectations (3.9.4)
|
||||
rspec-core (3.11.0)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-expectations (3.11.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-mocks (3.9.1)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-mocks (3.11.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-rails (3.9.1)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
rspec-expectations (~> 3.9.0)
|
||||
rspec-mocks (~> 3.9.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-support (3.9.4)
|
||||
rspec-support (~> 3.11.0)
|
||||
rspec-rails (5.1.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rspec-core (~> 3.10)
|
||||
rspec-expectations (~> 3.10)
|
||||
rspec-mocks (~> 3.10)
|
||||
rspec-support (~> 3.10)
|
||||
rspec-support (3.11.0)
|
||||
ruby_dep (1.5.0)
|
||||
ruby_parser (3.19.1)
|
||||
sexp_processor (~> 4.16)
|
||||
rubyzip (1.3.0)
|
||||
sass (3.7.4)
|
||||
sass-listen (~> 4.0.0)
|
||||
|
|
@ -199,6 +241,7 @@ GEM
|
|||
selenium-webdriver (3.142.7)
|
||||
childprocess (>= 0.5, < 4.0)
|
||||
rubyzip (>= 1.2.2)
|
||||
sexp_processor (4.16.1)
|
||||
spring (2.0.2)
|
||||
activesupport (>= 4.2)
|
||||
spring-watcher-listen (2.0.1)
|
||||
|
|
@ -211,6 +254,7 @@ GEM
|
|||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
temple (0.8.2)
|
||||
therubyracer (0.12.3)
|
||||
libv8 (~> 3.16.14.15)
|
||||
ref
|
||||
|
|
@ -257,16 +301,22 @@ DEPENDENCIES
|
|||
capybara (>= 2.15)
|
||||
chromedriver-helper
|
||||
coffee-rails (~> 4.2)
|
||||
database_cleaner
|
||||
devise
|
||||
factory_bot
|
||||
haml
|
||||
haml-rails
|
||||
html2haml
|
||||
jbuilder (~> 2.5)
|
||||
jquery-rails
|
||||
less-rails
|
||||
liquid-rails
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
mysql2 (>= 0.4.4, < 0.6.0)
|
||||
puma (~> 3.11)
|
||||
rails (~> 5.2.8)
|
||||
ransack
|
||||
rspec-rails (~> 3.0)
|
||||
rspec-rails (~> 5.1.2)
|
||||
sass-rails (~> 5.0)
|
||||
selenium-webdriver
|
||||
spring
|
||||
|
|
|
|||
|
|
@ -12,4 +12,5 @@
|
|||
//= require turbolinks
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require_tree .
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,8 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
protected
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :password, :password_confirmation, :address_attributes])
|
||||
devise_parameter_sanitizer.permit(:account_update, keys: [:email, :password, :password_confirmation, :current_password, address_attributes: [:state, :city, :address, :address2, :zipcode, :receiver, :phone] ])
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ class ProductsController < ApplicationController
|
|||
respond_to do |format|
|
||||
if @product.update(product_params)
|
||||
format.html { redirect_to product_url(@product), notice: "Product was successfully updated." }
|
||||
format.json { render :show, status: :ok, location: @product }
|
||||
format.json
|
||||
else
|
||||
format.html { render :edit, status: :unprocessable_entity }
|
||||
format.json { render json: @product.errors, status: :unprocessable_entity }
|
||||
format.json { render json: @product.errors.full_messages.join(', '), status: :error }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: 'from@example.com'
|
||||
default from: 'a410928612@163.com'
|
||||
layout 'mailer'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
class Address < ApplicationRecord
|
||||
belongs_to :user
|
||||
end
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
class LineItem < ApplicationRecord
|
||||
belongs_to :order
|
||||
belongs_to :variant
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class Order < ApplicationRecord
|
||||
belongs_to :user,counter_cache: true
|
||||
has_many :line_items
|
||||
has_many :variants, through: :line_items
|
||||
end
|
||||
|
|
@ -1,2 +1,6 @@
|
|||
class Product < ApplicationRecord
|
||||
class Product < ActiveRecord::Base
|
||||
validates :name, presence: true
|
||||
scope :state, -> { where(state:1) }
|
||||
scope :is_delete, -> { where("deleted_at is not null") }
|
||||
has_many :variants
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,5 +2,9 @@ class User < ApplicationRecord
|
|||
# Include default devise modules. Others available are:
|
||||
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :validatable
|
||||
:recoverable, :rememberable, :validatable,
|
||||
:confirmable
|
||||
has_one :address,dependent: :destroy
|
||||
accepts_nested_attributes_for :address, update_only: true
|
||||
has_many :orders
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
||||
|
||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
|
||||
<%= render "devise/shared/error_messages", resource: resource %>
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
<%= javascript_include_tag "application" %>
|
||||
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript"></script>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<div class="form-group">
|
||||
<%= f.label :name, :class => 'control-label' %>
|
||||
<%= f.label "名称", :class => 'control-label' %>
|
||||
<%= f.text_field :name, :class => 'form-control', required: true %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :description, :class => 'control-label' %>
|
||||
<%= f.label "描述", :class => 'control-label' %>
|
||||
<%= f.text_field :description, :class => 'form-control' %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :price, :class => 'control-label' %>
|
||||
<%= f.label "价格", :class => 'control-label' %>
|
||||
<%= f.text_field :price, :class => 'form-control' %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
$('#productsTable').prepend('<%= j render(@product) %>');
|
||||
$('#productFormModal').modal('hide');
|
||||
$('#newProductFormModal').modal('hide');
|
||||
$('#newProductForm')[0].reset();
|
||||
|
|
@ -36,8 +36,8 @@
|
|||
<%= render partial: "f", locals: {f: f} %>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<%= link_to t('.cancel', :default => t("helpers.links.cancel")), '#', :class => 'btn btn-default', data: {dismiss: "modal"} %>
|
||||
<%= f.submit nil, :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..." } %>
|
||||
<%= link_to "取消", '#', :class => 'btn btn-default', data: {dismiss: "modal"} %>
|
||||
<%= f.submit "确定", :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..." } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -57,28 +57,28 @@
|
|||
<div id="msg"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= label_tag "product[name]", Product.human_attribute_name("name"), :class => 'control-label' %>
|
||||
<%= label_tag "product[name]", "名称", :class => 'control-label' %>
|
||||
<%= text_field_tag "product[name]", "", :class => 'form-control', id: "editProductName", required: true %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= label_tag "product[description]", Product.human_attribute_name("description"), :class => 'control-label' %>
|
||||
<%= label_tag "product[description]", "描述", :class => 'control-label' %>
|
||||
<%= text_field_tag "product[description]", "", :class => 'form-control', id: "editProductDescription" %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= label_tag "product[price]", Product.human_attribute_name("price"), :class => 'control-label' %>
|
||||
<%= label_tag "product[price]", "价格", :class => 'control-label' %>
|
||||
<%= text_field_tag "product[price]", "", :class => 'form-control', id: "editProductPrice" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<%= link_to t('.cancel', :default => t("helpers.links.cancel")), '#', :class => 'btn btn-default', data: {dismiss: "modal"} %>
|
||||
<%= submit_tag t('.confirm', :default => t("helpers.links.confirm")), :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..." } %>
|
||||
<%= link_to "取消", '#', :class => 'btn btn-default', data: {dismiss: "modal"} %>
|
||||
<%= submit_tag "确定", :class => 'btn btn-primary', :data => { :"disable-with" => "请稍等..." } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<%= content_for :page_javascript do %>
|
||||
<%= javascript_include_tag "/app/assets/javascripts/products" %>
|
||||
|
||||
<script>
|
||||
$('#newProductFormModal').modal({
|
||||
show: false,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
json.id @product.id
|
||||
json.name link_to @product.name, product_path(@product)
|
||||
json.description @product.description
|
||||
json.price number_to_currency(@product.price)
|
||||
|
|
@ -28,6 +28,7 @@ test:
|
|||
<<: *default
|
||||
database: shop_test
|
||||
|
||||
|
||||
# As with config/secrets.yml, you never want to store sensitive information,
|
||||
# like your database password, in your source code. If your source code is
|
||||
# ever seen by anyone, they now have access to your database.
|
||||
|
|
|
|||
|
|
@ -58,4 +58,16 @@ Rails.application.configure do
|
|||
# Use an evented file watcher to asynchronously detect changes in source code,
|
||||
# routes, locales, etc. This feature depends on the listen gem.
|
||||
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
||||
# 邮箱配置
|
||||
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
||||
config.action_mailer.perform_deliveries = true
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
config.action_mailer.smtp_settings = {
|
||||
address: 'smtp.163.com',
|
||||
port: 25,
|
||||
user_name: 'a410928612@163.com',
|
||||
password: '834752287ZSXzsx',
|
||||
authentication: :plain,
|
||||
enable_starttls_auto: true
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ Devise.setup do |config|
|
|||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class
|
||||
# with default "from" parameter.
|
||||
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
|
||||
config.mailer_sender = 'a410928612@163.com'
|
||||
|
||||
# Configure the class responsible to send e-mails.
|
||||
# config.mailer = 'Devise::Mailer'
|
||||
config.mailer = 'Devise::Mailer'
|
||||
|
||||
# Configure the parent class responsible to send e-mails.
|
||||
# config.parent_mailer = 'ActionMailer::Base'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ class CreateProducts < ActiveRecord::Migration[5.2]
|
|||
t.string :name
|
||||
t.decimal :price
|
||||
t.text :description
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ class DeviseCreateUsers < ActiveRecord::Migration[5.2]
|
|||
# t.string :current_sign_in_ip
|
||||
# t.string :last_sign_in_ip
|
||||
|
||||
## Confirmable
|
||||
# t.string :confirmation_token
|
||||
# t.datetime :confirmed_at
|
||||
# t.datetime :confirmation_sent_at
|
||||
# t.string :unconfirmed_email # Only if using reconfirmable
|
||||
# Confirmable
|
||||
t.string :confirmation_token
|
||||
t.datetime :confirmed_at
|
||||
t.datetime :confirmation_sent_at
|
||||
t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
class AddStateToProduct < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :products, :state, :integer
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddDeletedAtToProduct < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :products, :deleted_at, :datetime
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
class CreateAddresses < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :addresses do |t|
|
||||
t.references :user, foreign_key: true
|
||||
t.string :state
|
||||
t.string :city
|
||||
t.string :address
|
||||
t.string :address2
|
||||
t.string :zipcode
|
||||
t.string :receiver
|
||||
t.string :phone
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
class CreateOrders < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :orders do |t|
|
||||
t.references :user, foreign_key: true
|
||||
t.string :number
|
||||
t.string :payment_state
|
||||
t.string :shipment_state
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddOrdersCountToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :orders_count, :integer
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
class CreateLineItems < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :line_items do |t|
|
||||
t.references :order, foreign_key: true
|
||||
t.references :variant, foreign_key: true
|
||||
t.integer :quantity
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
41
db/schema.rb
41
db/schema.rb
|
|
@ -10,29 +10,60 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_05_17_074708) do
|
||||
ActiveRecord::Schema.define(version: 2022_05_18_100755) do
|
||||
|
||||
create_table "products", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
create_table "addresses", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb3", force: :cascade do |t|
|
||||
t.bigint "user_id"
|
||||
t.string "state"
|
||||
t.string "city"
|
||||
t.string "address"
|
||||
t.string "address2"
|
||||
t.string "zipcode"
|
||||
t.string "receiver"
|
||||
t.string "phone"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["user_id"], name: "index_addresses_on_user_id"
|
||||
end
|
||||
|
||||
create_table "orders", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb3", force: :cascade do |t|
|
||||
t.bigint "user_id"
|
||||
t.string "number"
|
||||
t.string "payment_state"
|
||||
t.string "shipment_state"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["user_id"], name: "index_orders_on_user_id"
|
||||
end
|
||||
|
||||
create_table "products", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb3", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.decimal "price", precision: 10
|
||||
t.text "description"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "state"
|
||||
t.datetime "deleted_at"
|
||||
end
|
||||
|
||||
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb3", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "unconfirmed_email"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "orders_count"
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
||||
create_table "variants", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
create_table "variants", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb3", force: :cascade do |t|
|
||||
t.integer "product_id"
|
||||
t.decimal "price", precision: 8, scale: 2
|
||||
t.string "size"
|
||||
|
|
@ -40,4 +71,6 @@ ActiveRecord::Schema.define(version: 2022_05_17_074708) do
|
|||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_foreign_key "addresses", "users"
|
||||
add_foreign_key "orders", "users"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
FactoryGirl.define do
|
||||
factory :address do
|
||||
user nil
|
||||
state "MyString"
|
||||
city "MyString"
|
||||
address "MyString"
|
||||
address2 "MyString"
|
||||
zipcode "MyString"
|
||||
receiver "MyString"
|
||||
phone "MyString"
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Address, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe LineItem, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Order, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
|
|
@ -3,3 +3,10 @@ require 'rails_helper'
|
|||
RSpec.describe Product, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
RSpec.describe Product, type: :model do
|
||||
it "should create a product" do
|
||||
tshirt = Product.create(name: "T-Shirt", price: 9)
|
||||
expect(tshirt.name).to eq("T-Shirt")
|
||||
expect(tshirt.price).to eq(9)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
require 'spec_helper'
|
||||
ENV['RAILS_ENV'] ||= 'test'
|
||||
require_relative '../config/environment'
|
||||
|
||||
require File.expand_path('../config/environment', __dir__)
|
||||
|
||||
# Prevent database truncation if the environment is production
|
||||
abort("The Rails environment is running in production mode!") if Rails.env.production?
|
||||
require 'rspec/rails'
|
||||
|
|
@ -20,7 +22,7 @@ require 'rspec/rails'
|
|||
# directory. Alternatively, in the individual `*_spec.rb` files, manually
|
||||
# require only the support files necessary.
|
||||
#
|
||||
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
|
||||
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
|
||||
|
||||
# Checks for pending migrations and applies them before tests are run.
|
||||
# If you are not using ActiveRecord, you can remove these lines.
|
||||
|
|
@ -39,9 +41,6 @@ RSpec.configure do |config|
|
|||
# instead of true.
|
||||
config.use_transactional_fixtures = true
|
||||
|
||||
# You can uncomment this line to turn off ActiveRecord support entirely.
|
||||
# config.use_active_record = false
|
||||
|
||||
# RSpec Rails can automatically mix in different behaviours to your tests
|
||||
# based on their file location, for example enabling you to call `get` and
|
||||
# `post` in specs under `spec/controllers`.
|
||||
|
|
@ -49,7 +48,7 @@ RSpec.configure do |config|
|
|||
# You can disable this behaviour by removing the line below, and instead
|
||||
# explicitly tag your specs with their type, e.g.:
|
||||
#
|
||||
# RSpec.describe UsersController, type: :controller do
|
||||
# RSpec.describe UsersController, :type => :controller do
|
||||
# # ...
|
||||
# end
|
||||
#
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# the additional setup, and require it from the spec files that actually need
|
||||
# it.
|
||||
#
|
||||
# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||
RSpec.configure do |config|
|
||||
# rspec-expectations config goes here. You can use an alternate
|
||||
# assertion/expectation library such as wrong or the stdlib/minitest
|
||||
|
|
@ -61,7 +61,9 @@ RSpec.configure do |config|
|
|||
|
||||
# Limits the available syntax to the non-monkey patched syntax that is
|
||||
# recommended. For more details, see:
|
||||
# https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode
|
||||
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
||||
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
||||
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
||||
config.disable_monkey_patching!
|
||||
|
||||
# Many RSpec users commonly either run the entire suite or an individual
|
||||
|
|
|
|||
Loading…
Reference in New Issue