尝试用rails发送邮件、了解rails视图和模板引擎、了解并上手rails模型查询和关联的一些相关操作

This commit is contained in:
zhoushixu 2022-05-18 18:21:11 +08:00
parent 1b53a06e65
commit 121a18dbd0
37 changed files with 333 additions and 64 deletions

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -12,4 +12,5 @@
//= require turbolinks
//= require jquery
//= require jquery_ujs
//= require_tree .

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
default from: 'a410928612@163.com'
layout 'mailer'
end

3
app/models/address.rb Normal file
View File

@ -0,0 +1,3 @@
class Address < ApplicationRecord
belongs_to :user
end

4
app/models/line_item.rb Normal file
View File

@ -0,0 +1,4 @@
class LineItem < ApplicationRecord
belongs_to :order
belongs_to :variant
end

5
app/models/order.rb Normal file
View File

@ -0,0 +1,5 @@
class Order < ApplicationRecord
belongs_to :user,counter_cache: true
has_many :line_items
has_many :variants, through: :line_items
end

View File

@ -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

View File

@ -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

View File

@ -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 %>

View File

@ -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>

View File

@ -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>

View File

@ -1,2 +1,3 @@
$('#productsTable').prepend('<%= j render(@product) %>');
$('#productFormModal').modal('hide');
$('#newProductFormModal').modal('hide');
$('#newProductForm')[0].reset();

View File

@ -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,

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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'

View File

@ -4,7 +4,6 @@ class CreateProducts < ActiveRecord::Migration[5.2]
t.string :name
t.decimal :price
t.text :description
t.timestamps
end
end

View File

@ -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

View File

@ -0,0 +1,5 @@
class AddStateToProduct < ActiveRecord::Migration[5.2]
def change
add_column :products, :state, :integer
end
end

View File

@ -0,0 +1,5 @@
class AddDeletedAtToProduct < ActiveRecord::Migration[5.2]
def change
add_column :products, :deleted_at, :datetime
end
end

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
class AddOrdersCountToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :orders_count, :integer
end
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Address, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe LineItem, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Order, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -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

View File

@ -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
#

View File

@ -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