【命令笔记】【长期更新】rails常用命令

Published on:

git commit重命名
git commit --amend 修改最后一次commit
参考资料https://github.com/uolcano/blog/issues/12

推github失败

git push --all origin --force(如果确定本地是正确的,可以强推)

git push origin --delete (删除指定远程分支)

1-1 分支的删除/恢复

git branch -D 分支名(删除指定分支)

分支的恢复:
git reflog(查看分支ID)
git branch 分支名 分支ID

2-1 commit的删除/恢复

  • commit的删除:

    git log(查看现存commit的历史,按`q键`退出)
    git reset --hard HEAD~1(数字代表删除多少个分支)
    
  • commit的恢复:

    git reflog(查看commit历史,包括现存和已删除的,按`q键`退出)
    复制分支名字
    git reset --hard 想恢复的commitID(恢复指定commit)
    

  • (不常用)其他操作:把commit恢复到新建分支上
    git reflog(查看commit历史,包括现存和已删除的,按q键退出)
    复制分支名字
    git branch recover_新分支名 commit_id (比如git branch recover_9999 179577c)
    

2-2 合并分支(commit的复制)

git merge 想合并的分支名称(相当于复制了克隆分支上,不一致的commit点——即commit的复制)

Nic老师使用场景:
在开发时习惯有一只产品分支比如prodt,一只测试分支比如test(test要从prodt分支git checkout -b新建的,或是说是prodt的克隆品)。
平时在test分支随便玩,测试好功能就在test上commit保存,烂掉的分支可用git stash等。
test上commit后切换到prodt分支,最后git merge test 合并。

2-3(不常用)当前分支上做烂了——情景1.有touch新建文件时 (commit的剪切)

当前分支不要git add .不要git commit,直接新建分支,在新分支上commit保存,最后切回原来的分支(临时保存的分支如果不要了可以删除git branch -D 临时分支名)——【可以用来做commit的剪切,从test分支剪切到prodt产品分支】

git checkout -b 临时分之名
git add .
git commit -m "linshifenzhi"
git checkout 刚刚在做的分支名

2-4(常用)当前分支上做烂了——情景2.没有touch新建文件时

git status (查看已更改文件)
git stash 或者 
git stash save 本次暂存的名字(一次临时的commit,即暂存)

Nic老师使用场景:正在做分支1还没有保存,老板叫你马上做分支2,这时在分支1上git stash。然后切换到分支2上工作,完工commit保存后,想继续做分支1。切换回分支1,然后git stash pop,就回到刚刚被老板打断的位置。

git stash的 删除/恢复(一般不做删除操作)

  • git stash恢复:

    git stash list(显示暂存清单,按`q键`退出)
    git stash pop(恢复到最后一次的操作) 
    git stash pop 某次暂存的ID如stash@{0}(恢复到特定某次的操作)
    
  • git stash删除:

    git stash drop(删除最新操作)
    git stash drop 某次暂存的ID如stash@{0} (删除特定某次的操作)
    git stash clear(删除所有暂存)
    

clone的时候只有master分支:

git branch -a 或者
git fetch origin

数据文件——新建/删除

rails g controller xxx
rails g model xxx
rails d controller xxx
rails d model xxx

数据重置——rake三兄弟

rake db:drop
rake db:create
rake db:migrate

推heroku报错1(原heroku已删除)

git push heroku step8:master
remote: ! No such app as blooming-earth-94985.
fatal: repository 'https://git.heroku.com/blooming-earth-94985.git/' not found
git logs
Couldn't find that app.

git remote rm heroku(如果是github的用git remote rm/add origin)
heroku apps 查看名称
git remote add heroku https://git.heroku.com/名称.git(或git@heroku.com:名称.git)
git push heroku 分支名:master

Nic老师说,这个办法是特效药,如果有时间的话,还是先尝试修复的方法。比如你去公司上班,然后数据库有问题,是不可能把几万笔数据rm的。

推hero库报错2

git push heroku 分支名:master
heroku pg:reset DATABASE(清空heroku数据库,比如旧的seed档)
heroku run rake db:migrate
heroku run rake db:seed

https://forum.qzy.camp/t/heroku-push-migrate/1529
对于precompile,当由于可能有文件没生效,导致出现push到Heroku上出现远端画面和本地服务器画面不一致的情形时,执行rake assets:precompile可以吧app/assets的静态文档压缩到public/assets,使得浏览器能够访问到。

rake assets:precompile
git add .
git commit -m "vendor compiled assets"
重新git push heroku 分支名:master

rake的前进后退

rake db:migrtae前进保存
rake db:rollback后退一步,修改后再rake db:migrtae
rake db:rollback STEP=10后退10步

【转发】 求职面试题目整理

Published on:

我们绝大部分同学之前都不是程序员,在求职过程中难免会遇到各种问题。一个人求职太孤独,不如大家一起结伴打怪。
我建了个微信群,大家可以在这个群里相互交流职位信息、简历投递技巧、面试经验,面试、笔试题目。大家相互帮助,找到合适的工作

如果扫码无效,可以加我的个人微信:185-5166-4870,注明求职交流群,我会拉你进群。

面试官并没有提前仔细看我的简历,所以先让我做自我介绍,随便讲讲,所以我就把简历上的东西口述了一遍。

1.Ruby的特点是什么?你对ruby的理解是什么?
注意:
1)问的不是rails的特点。因为我们的教材直接学的rails,所以很容易答非所问。
2)这个问题很多东西我也还没有搞懂,不过我个人认为只要能回答出一部分就可以。对Ruby的理解应该会随着学习的不断深入而不断变化。

Ruby 的特点

Ruby的特点

我为什么喜欢Ruby

1)Ruby从人、工程师的角度考虑问题,而不是从计算机的角度考虑问题。我们是主人,他们是仆人。遵循上述理念,Ruby语言非常直观,按照工程师认为它应该的方式运行。

2)完全面向对象:Ruby从一开始就是彻底的面向对象的。Ruby中一切都是对象,都拥有属性和方法。包括基本数据类型(primitive data types),比如字符串、整数 都是对象。甚至常量也会被当做对象处理,所以一个方法的接收者,可以是一个常量。
所以Ruby中所有语句都是方法调用,这样就更统一。

3)是动态语言,可以动态修改对象、类别:可以在程序中修改先前定义过的类,也可以在某个类的实例中定义该实例特有的方法,这叫做原型方法。
高度灵活性:可以自由地去改变语言的各个部分。其核心部分也可以被移除或重新定义,现有的部分也可以继续添加内容。

class DemoClass
def methodA
"general methodA"
end
end

dc = DemoClass.new
dc.methodA # "general methodA"

def dc.methodA
"special for this instance."
end

dc.methodA # "special for this instance."
4)变量无需声明,变量没有类型:不像静态语言需要事先声明变量的类型,Ruby的变量是动态类型,给变量赋予什么类型该变量就是什么类型。

5)单类继承 + 模块扩展:既保证了单类继承的简单,又能为某些类添加共同的方法。

6)有丰富的类库。
人性化:当你想要一个方法的时候,绝大多数时候它已经在那里了。

7)理解正则表达式

8)命令行交互工具irb非常方便,可以随时验证一些想法

9)多平台

10)强大的元编程:Ruby的反射功能非常强大,甚至可以自行追踪程序运作,或是取出private变量、拦截方法的调用。常常与’可以动态地修改对象’这项特色结合,实现元编程:程序运行时,可以由程序员提供的信息,自行生成、修改类别或对象,这能大大提高编程效率。

11)任何东西都有值:不管是四则运算、逻辑表达式还是一个语句,都有回传值

12)有垃圾回收机制

2.Ruby中有哪些动态方法调用?各自的优劣?

在编译阶段,编译器就会检查方法调用的对象是否有一个这样的方法,如果没有就直接报错,这种称为静态类型检查,这种语言称为静态语言。ruby是动态语言,只有真正调用这个方法的时候,找不到这个方法才会报错。

Ruby 动态方法

为何Ruby的元编程能力如此强大?因为它能够在运行时生成需要的代码,或者调用相应的方法。这给Ruby程序增加了灵活性。

不用对象.方法的方式调用,而用send方法来调用函数,这种调用方式叫做动态指派。这种方法更加清晰地说明调用方法的概念:调用一个方法实际上就是给对象发送一条消息。这里可以看成是我们给对象 send一个消息my_method以及参数3.
使用send动态调用的好处是,可以在编码中动态地决定方法调用。

ruby 元编程 读书笔记

class MyClass
def my_method(my_arg)
my_arg * 2
end
end

obj = MyClass.new
obj.my_method(3) #=> 6
obj.send(:my_method, 3) #=> 6
1)send
2)使用Object类的method方法来获取某个方法,这个方法返回一个method类的对象。再使用call方法来执行方法调用,算是延迟调用。
可以在使用对象的任何地方使用method对象,当调用call方法时,参数所指明的方法会被执行。你可以把method对象作为一个迭代器使用。
3)使用eval方法 eval方法会分析其后的字符串参数,并把这个字符串参数作为ruby代码执行。

ruby方法的动态调用

都可以调用私有方法。只有public_send才是不可以调用私有方法.
method call执行速度最快。
发送偶尔需要动态调用方法时会用到 send。但是绝少会用到eval,因为太危险了。eval评估任意表达式,不仅仅是调用方法。

3.Ruby中单引号和双引号的差别。
Ruby 字符串生成有两种方式,字符串内容加单引号或双引号。
单引号中的内容不会被转义(处理),双引号中的内容会被转义。

name = “foobar"
string = "#{name}"

=> foobar

string = '#{name}'

=> #{name}

4.一个rails 项目的架构,或者说一个rails专案的主要目录、文件有那些,各自的作用是什么?
app
assets #静态档案
images
javascripts
application.js
stylesheets
application.css
controllers #把Ruby的objects在model和view之间传来传去。每个URL都对应controller里面一个特定的method

models #数据库和你的程序的之间的桥梁
views #产生HTML来显示在浏览器
common
layouts

helpers #views中过多的逻辑判断类的东西,可以在helper中定义好,views中直接调用即可
jobs
mailers

config
deploy
environments

development.rb
production.rb
test.rb
routes.rb #路径

db
migrate
schema.rb
seeds.rb

lib

public #唯一一个放什么就会出现什么的文件夹,sever会直接回传,不会经过rails处理
test
tmp
vendor #放第三方的CSS/JS库的源码
assets
javascripts
stylesheets

.gitignore
Gemfile
Gemfile.lock
README.md

5.说说你对active record的理解?
active record是MVC中的M(model),负责对象的创建和和将数据存储到数据库中。active record库的主要作用是把Ruby对象映射到数据表中,这个功能称为对象关系映射(ORM),它结合了关系数据库(用于持久化)和面向对象编程(用于业务逻辑)的优点。
使用ORM,可以很容易地从数据库存储和检索对象的数据,不用写那些繁杂的数据库语句。
active record最重要的功能包括:
1)将model和data联系起来
2)将各个model联系起来,理清了他们的继承、层级关系
3)在model存入数据库前,对他们做有效性验证
4)用面向对象的方式对数据进行操作

2.对controller的理解
Action Controller 是MVC中的C(控制器)。控制器是模型和视图的中间人,路由决定使用哪个控制器处理请求后,控制器负责接收、解析请求,从模型中获取数据,或把数据写入模型,再通过视图生成相应的HTML。

6.执行rails s时背后发生了什么?
登录了一个叫做puma的网络服务器,它是和rails绑定的。你想通过浏览器访问你的rails应用时就可以使用rails s。
从敲下rails s命令开始,到服务器启动起来的过程:rails命令行解析,创建Rails::Server 对象,加载Rails.application,启动服务器监听用户请求。rack

port -p
environment -e
IP -b
daemon -d

rails s 启动过程分析

1.你的jdstore中有哪些model?关联关系是怎样的?

user has_many :comments has_many :orders #用户只和评论、订单有关联,和购物车并无关联
category has_many :products
product belongs_to :category has_many :comments
comment belongs_to :user belongs_to :product
cart has_many :cart_items has_many :products, through: :cart_items, source: :product
cart_item belongs_to :cart belongs_to :product
order belongs_to :user has_many :product_lists #订单和购物车也没有关系
productlist belongs_to :order
7.你的购物网站中 加入购物车如何设计?逻辑是什么?怎么能防止同一个商品重复加入购物车?
这个地方的model比较特殊:要设计一台购物车cart(Model),还要设计一个cart_item的model。因为购物车中会有多种商品,而每种商品又有各自的购买数量、价格等,设计成这种”嵌套”的model,会更直观。
rails g model cart
rails g model cart_item

db/migrate/xxx_create_cart_items.rb
class CreateCartItems < ActiveRecord::Migration[5.0]
def change
create_table :cart_items do |t|
t.integer :cart_id
t.integer :product_id
t.integer :quantity, default: 1
end
end
end
app/models/cart_item.rb
class CartItem < ApplicationRecord
belongs_to :cart
belongs_to :product
end
add_to_cart这个action要分为两部分来实现:add_product_to_cart和current_cart

app/models/cart.rb
class Cart < ApplicationRecord
has_many :cart_items
has_many :products, through: :cart_items, source: :product

def add_product_to_cart(product)
ci = cart_items.build
ci.product = product
ci.quantity = 1
ci.save
end
end
每个进店的用户,不管是否登入,都要准备一台购物车

app/controllers/applications_controller.rb
class ApplicationController < ActionController::Base

helper_method :current_cart

def current_cart
@current_cart ||= find_cart
end

private

def find_cart
cart = Cart.find_by(id: session[:cart_id])
if cart.blank?
cart = Cart.create
end
session[:cart_id] = cart.id
return cart
end
end
每个人进店时,都会有个session,上面记录了你拿了哪台购物车cart_id。所以,current_cart就是通过这样的方式存取的。万一你的车丢了if cart.blank?,会再给你一台车。

购物车中的信息存到了哪里?
存到cart和cart_items了。session中只记录了cart id。
购物车和user并没有练习在一起。所以,加入购物车时不需要强制用户登录。
当建立订单的时候order时,强制用户登录,这时@order.user = current_user,才将当前用户和购物车联系在了一起。

app/controllers/products_controller.rb
def add_to_cart
@product = Product.find(params[:id])
if !current_cart.products.include?(@product)
current_cart.add_product_to_cart(@product)
else
flash[:notice] = "购物车内已有此商品"
end
redirect_to :back
end
end
8.你的购物网站中建立订单、结账付款的设计逻辑是什么?

在购物车按下确认结账按钮后,可以显示结账明细,并且可以让消费者输入寄送地址。

rails g model order

app/controllers/carts_controller.rb
class CartsController < ApplicationController
def checkout
@order = Order.new
end
end
rails g controller orders

rails g model product_list

app/controllers/orders_controller.rb
class OrdersController < ApplicationController

def create
@order = Order.new(order_params)
@order.user = current_user
@order.total = current_cart.total_price

if @order.save

  current_cart.cart_items.each do |cart_item|
    product_list = ProductList.new
    product_list.order = @order
    product_list.product_name = cart_item.product.title
    product_list.product_price = cart_item.product.price
    product_list.quantity = cart_item.quantity
    product_list.save
  end

  redirect_to order_path(@order)
else
  render 'carts/checkout'
end

end

def show
@order = Order.find(params[:id])
@product_lists = @order.product_lists
end

private

def order_params
params.require(:order).permit(:billing_name, :billing_address, :shipping_name, :shipping_address)
end
end
rails g migration add_is_paid_to_order
rails g migration add_payment_method_to_order

db/migrate/xxx_add_is_paid_to_order.rb
def change
add_column :orders, :is_paid, :boolean, default: false
add_column :orders, :payment_method, :string
end
config/routes.rb
resources :orders do
member do
post :pay_with_alipay
post :pay_with_wechat
end
end
app/controllers/orders_controller.rb
def pay_with_alipay
@order = Order.find_by_token(params[:id])
@order.set_payment_with!("alipay")
@order.pay!

   redirect_to order_path(@order.token), notice: "使用支付宝付款成功”
end

def pay_with_wechat
    @order = Order.find_by_token(params[:id])
    @order.set_payment_with!("wechat")
    @order.pay!

    redirect_to order_path(@order.token), notice: "使用微信付款成功"
 end

app/models/order.rb
class Order < ApplicationRecord

def set_payment_with!(method)
self.update_columns(payment_method: method)
end

def pay!
self.update_columns(is_paid: true)
end

end
4.购物网站中发送邮件通知 是如何设计的?
rails g mailer OrderMailer

app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "service@jdstore.com"
layout 'mailer'
end
app/mailers/order_mailer.rb
class OrderMailer < ApplicationMailer
def notify_order_placed(order)
@order = order
@user = order.user
@product_lists = @order.product_lists

 mail(to: @user.email , subject: "[JDstore] 感谢您完成本次下单,以下是您这次购物明细 #{order.token}")
end

end

touch app/views/order_mailer/notify_order_placed.html.erb

app/controllers/orders_controller.rb
class OrdersController < ApplicationController
before_action :authenticate_user!

def create
@order = Order.new(order_params)
@order.user = current_user
@order.total = current_cart.total_price

if @order.save

  current_cart.cart_items.each do |cart_item|
    product_list = ProductList.new
    product_list.order = @order
    product_list.product_name = cart_item.product.title
    product_list.product_price = cart_item.product.price
    product_list.quantity = cart_item.quantity
    product_list.save
  end
  current_cart.clean!
  OrderMailer.notify_order_placed(@order).deliver!

  redirect_to order_path(@order.token)

 else
   render 'carts/checkout'
 end

end
5.切换订单状态
用有限状态机这个架构实作。

gem 'aasm'

rails g migration add_aasm_state_to_order

db/migrate/xxx_add_aasm_state_to_order.rb
class AddAasmStateToOrder < ActiveRecord::Migration
def change
add_column :orders, :aasm_state, :string, default: "order_placed"
add_index :orders, :aasm_state
end
end
app/models/order.rb
include AASM

aasm do
state :order_placed, initial: true
state :paid
state :shipping
state :shipped
state :order_cancelled
state :good_returned

event :make_payment, after_commit: :pay! do 
  transitions from: :order_placed, to: :paid
end

event :ship do 
  transitions from: :paid,     to: shipping
end

event :deliver do 
  transitions from: :shipping,  to: :shipped
end

event :return_good do
  transitions from: :shipped,   to: :good_returned
end

event :cancel_order do 
  transitions from: [:order_placed, :paid], to: :order_cancelled
end

end
namespace :admin do
resources :orders do
member do
post :cancel
post :ship
post :shipped
post :return
end
end
end
app/controllers/admin/orders_controller.rb
class Admin::OrdersController < ApplicationController
def ship
@order = Order.find(params[:id])
@order.ship!
redirect_to :back
end

def shipped
@order = Order.find(params[:id])
@order.deliver!
redirect_to :back
end

9.自动化测试的逻辑是什么?怎么写?
自动化测试,就是用程序去测试程序。开发过程中不需要再打开rails s 或rails c 检查结果是否正确了。
使用自动化测试框架rspec进行测试。

leap_year_spec.rb
describe " " do
it " " do
result = is_leap_year?(2016)
expect(result).to eq(true)
end

end
其中每个it包起来的就是一个测试案例,用expect方法检查结果是否如我们所预期。
执行 rspec + 测试文件名

测试其实就是调用代码中的action/method,代入各种可能的参数,然后用expect方法检查result是否正确。
测试代码比实作代码 还多行是正常的,测试代码非常易读:1.建立测试资料,2.执行程序,3.检查结果

准备测试案例是写测试的关键,也就是说,要测哪些案例才算这个程序是正确的?因此,在开始写代码前,要先列出所有可能测试的案例的清单,特别是边界的情况。列出所有需要测试的可能情况后,再删掉明显重复的案例。

要看到测试失败,才表示测试真正在起作用。所以,不一定要先写实作代码再写测试代码,而是可以先写测试代码再写实作代码。

案例和案例之间是互相独立、互不影响的,这样测试失败时,才不用怀疑是不是被别的测试影响的。因此新增加的测试案例的对象需要重新建立。

不要一开始就把全部测试案例都写出来,这样要一次通过所有测试会很辛苦。而是要新写一段测试代码让测试失败,然后改实作代码让测试通过。然后再新写下一个测试代码让测试失败,然后再改实作,如此迭代交替。TDD(test-driven development)

在测试代码中,你可以直接puts变量,跑测试的时候就会输出,这是最简单的除错方式;你也可以在任意的位置放byebug设置中断点,就会在执行那一步时停下来,可以检查变量,输入continue就会继续执行。

自动化测试分为几种不同的类型,针对单一类别的方法进行测试,叫做单元测试。

11.你对user story 用户故事如何理解?

用户故事,是加上了角色的需求、功能。只有从角色的角度出发去思考,梳理需要的功能,做出的功能才会符合角色真正的、真实的需求。如果不考虑角色,只按照所谓各类型网站的标准去开发,一是会觉得很乱、很多,理不清;二是会做的太多、太少或做歪。

某角色,需要做什么事,这件事要在哪里做?这件事由哪些要素组成?这就是最终可以实作的步骤。(全栈营的招聘网站教程第4章 是在一步步带我们达成这一点。先是随机列出所有你能想到的功能,然后从中找出这个项目的所有角色,然后以各个角色为中心来整理每个角色的需求,也就是从角色的角度来表述网站的功能。然后就是不断细化每个角色的需求或者说要具有的功能,即不仅要说明角色要做什么事,还要说明在哪里做(后台、首页、、、?)、然后是这件事、这个事物由哪些要素构成?(比如文章包括标题、内容...),一直细化、全面到能实作的地步,也就是能由此而确定需要哪些model、需要哪些页面。

拆解任务,最终要把把大问题、需求、项目拆解成可以实作、执行的小问题、步骤。
无论这个需求看上去多么小,比如电商网站中消费者可以很方便地购买商品并结账,购买商品就是加入购物车,这很简单。而生成订单并结账则需要分出好几个步骤:消费者点击结账后,首先要进入地址等信息的填写确认页面;然后是付款页面,付款后商家也需要收到订单通知;商品库存需要随之减少、、、、、、是否是可用的用户故事,就要看每个步骤是不是可以实作的,是否可以将其转化为代码。

团队成员认领的是用户故事还是任务

12.你对敏捷项目管理如何理解?

真实的项目非常复杂,有很多user story,会产生很多bug。
如果对截止时间没有清醒的认识,非要一次就做成非常牛逼的产品,把时间压到最后一刻。最终得到的只能是无法按时完成,有各种bug,只能焦头烂额地加班。又因为墨菲定律,在如此紧张的时间压迫下,你出错的概率会大大提高,于是陷入恶性循环。

项目管理的核心就是时间管理。做任何计划时都要预留额外的时间,因为永远会有意外发生。
因为时间、人力永远是有限的,所以我们的目标不是一次就做出牛逼的、完美的产品,而是做符合市场需求的、最小可行性产品。
根据这个定义排列优先级:
1.保留足够的测试时间:不论项目大小,都应该拿出1/3时间来测试,让真实用户做充分的测试,尽可能排除bug。
2.剩余2/3的时间分为三部分:
(1)必须有的基础。
(2)先做主干功能:砍掉不必要的功能,只做 must have 和should have, 先不管could have 和 nice to have。
(3)填补细节:按照剩余的时间,能做多少做多少,不要勉强。
之所以可以按照情况先砍掉相对不重要的功能,一是因为时间有限,二是因为项目是活的,做的过程中会发现很多东西跟之前想的不一样,所以可以按照实际情况调整。

一开始就要先部署,因为本地环境和远端环境不同,如果全部写完再部署会出现很多bug,先部署好之后,每做一个功能立即更新一下看是否有bug即可。

1.each 和 map 的区别?

each 将block作用于数组中的每个元素,但对原数组并无影响,return 的结果仍为原数组。常用于数组的循环操作

[1,2,3,4].each {|n| puts n*2}

Outputs:

2

4

6

8

map 和 collect一样(实际上map是collect的alias),将block应用于数组中的所有元素,并使原数组 变成一个新数组

[1,2,3,4].map {|n| n*2}

=> [2,4,6,8]

Campaign.where(finish_remark:"stop from api").each {|c| c.id} 会输出各个campaign的所有信息。因为each方法return的就是原数组。
Campaign.where(finish_remark:"stop from api").map {|c| c.id}则会只输出id,因为map会输出新数组。
Campaign.where(finish_remark:"stop from api").map {&:id}
2.ruby 中的变量不需要提前定义,那么 print 'a'会得到什么结果?

print "a"
a => nil
nil是print方法的返回值

3.users的数据库如下:

id city
1 杭州
2 杭州
3 南京
4 北京

用SQL数据库语句或ruby语句计算users的总人数,各个城市的人数?

guides.ruby-china.org
这个题目我也只是根据链接中的材料写出来的答案,不知道是否正确。敬请指正!

总人数User.count
杭州人数User.where("city = '杭州'").count

7.rails里不是有联表查询吗,如果我把联表查询分成多条独立的查询语句来查询的话,这两种方式的查询效率那个快?
你没有问我这个联表里有没有写索引。假如说没有写索引,哪个查询速度更快?
没写索引时,只能一笔笔地循序找,那独立快。有索引时,联表查询快。

假如你有一条慢查询,一般你会通过哪几个方面去优化查询?
includes——N+1 query
加索引——table scan
select-只拿需要的列
计数快取--counter_cache
find_in_batches——巨量数据

对于比较慢的联表查询,这里再给你提供两种方式:
一是如果联表查询联的表较多,可以在中间表做数据备份或减少不必要的中间表;
二是如果查询量大,且有锁表,可以考虑使用存储过程。

1.Rails的原则是什么?
rails是使用Ruby语言编写的web应用开发框架。
1)不要自我重复(DRY):代码才更容易维护,更具扩展性。
2)多约定,少配置:为大多数需求都提供了最好的解决方法,并默认使用这些约定。

3.数据验证应该放在那里?
在模型层做数据验证最具有普适性。
数据库约束和存储过程 无法兼容多种数据库,而且难以测试和维护。
客户端验证很有用,但单独使用时可靠性不高。如果使用JavaScript实现,用户在浏览器禁用JavaScript后很容易跳过验证。
控制器层验证一般都不灵活,难以测试和维护。并且我们要尽可能保证控制器的代码简洁。

4.关联有哪几种?

belongs_to
has_one
has_many

has_many :through
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end

class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
has_one :through
class Supplier < ApplicationRecord
has_one :account
has_one :account_history, through: :account
end

class Account < ApplicationRecord
belongs_to :supplier
has_one :account_history
end

class AccountHistory < ApplicationRecord
belongs_to :account
end
has_and_belongs_to_many

多态关联:一个模型可以属于多个模型

class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end

class Employee < ApplicationRecord
has_many :pictures, as: :miageable
end

class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
自联结:模型和自己建立关系

7.用的哪个数据库?
开发用sqlite,部署到heroku用postgresql,自学MySQL

10.团队合作过吗?还是都是自己写的?
有过合作呀,购物网站就是两人合作的成功,我做的主程,通过GitHub远程合作。

1.除了rails,你还用过或者看过其他的ruby框架吗?

什么是网站开发框架? rails实战圣经
讨论版、blog、内容管理系统(CMS)、wiki,这类系统的重点主要在资料的保存和显示,牵扯的复杂商业逻辑不多。程序只是数据库系统的糖衣接口,不需要MVC架构,不需要页面与程序逻辑分开,不需要对象导向。

随着web2.0和云端风潮带来越来越多的web应用程序的开发需求,网站、应用的规模增加,需要加入更多的商业逻辑和功能。之前的开发方式导致整个项目的结构变得十分复杂,不利于团队合作开发。要接受维护这样的网站,常常会不知道如何阅读及修改,因为所有的商业逻辑与HTML混杂在一起,不同的人开发就有不同的程序架构,缺乏程序文件是常有的事,也不容易进行测试。

框架就是制定好了一套规范和惯例,框架的功能类似于基础设施,与具体的软件应用无关。

通过MVC这一软件架构设计模式,我们可以有系统地组织代码,分离商业逻辑和使用者接口,让前端和后端开发者可以独立作业。

10 alternative Ruby web frameworks

Ruby的备选web开发框架

2.除了heroku,你还用过其他的web server吗?
linode server、阿里云

6.你开发网站是前后端分离,还是直接后端渲染?
完完全全分离,后端负责提供API, 独立前端 消费API 这样对前端和后端都是比较爽的。
但Rails开发者更多是前后端一起搞的

4.平时应该是在mac下编程吧,对linux熟悉吗?
基本的命令知道,部署capistrano时在远端也用到过一些

七、如何保存、验证用户密码?是直接存到数据库吗?
用户注册时输入的密码,在实际存储进数据库时,会先经过散列函数,变成摘要值。数据库里没有存用户的明码,而是存密码摘要后的值。下次用户登录的时候,将用户密码再摘要一次,与数据库中存的密码摘要 进行比对即可。

一、以下两个@a 是不是同一个实例变量?

class A

def self.fang
@a = 1
end

def zheng
@a = 1
end
不是

上面的是个类方法,其中的@a是个类实例变量,下面的是个实例方法,其中的@a是个实例变量。
class variable在整个class继承体系都是指同一个,而class instance variable则是各个class都不同,因此class instance variable很多时候比class variable好用,像是参数化的classes。
class variable / class instance variable / instance variable
class instance variables

遇到class、module、def,程序会进入一个新的作用域

self和作用域

二、

module A
def self.B

end
end

class C

include A

extend A
end
都会发生错误。module内用self定义的方法,是module的class method,只能用A.B调用,跟include、extend无关。

is it possible to define a class method in a module?

五、

父类
def A(a,b)

end

子类
def A(a)

end
要看A方法是否支持只有一个参数的情况,如果不支持则发生错误。

5.如果给你一台阿里云的服务器,让你把你github上的代码部署上去,你会做些什么?
新增部署用账号apps
安装ruby 环境,安装Ruby
安装RMagick
安装passenger(rails用http server)
安装Nginx并整合passenger
安装rails
安装数据库如postgresql

直接用capistrano 部署:
gem 'capistrano'
生成远端机器的key
设定Nginx
安装Capistrano-passenger

只有passenger做web server吗?Nginx也是web server吗?你有没有想过nginx也是web server,passenger也是web server,为什么要多此一举?
Nginx其实是反向代理服务器
正向代理与反向代理

8.安全方面学习了哪些?
1)XSS跨站脚本攻击:恶意用户会张贴JavaScript代码,其他用户浏览时浏览器就会执行JavaScript。
2)CSRF跨站请求伪造
3)SQL injection 攻击
4)大量赋值: 用strong parameters防御
5)破解加密:用session而不是cookie
6)DOS拒绝服务攻击:大量发送http请求,让你的服务器忙不过来。只能想办法识别攻击方的IP,然后进行封锁。

5.gem用过哪些?

gem 'bootstrap-sass'
gem 'jquery-ujs'
gem 'jquery-rails'

gem 'simple_form'
gem 'font-awesome-rails'

gem 'devise'
gem 'devise-i18n'
gem 'rucaptcha' #注册验证码

gem 'pundit'
gem 'cancancan' #权限

gem 'will_paginate'
gem 'kaminari'

gem 'carrierwave'
gem 'mini_magick'

gem 'select2-rails' #单选、多选
gem 'nested_form_fields' #嵌套表单
gem 'boostrap-datepicker-rails' #选时间日期的

gem 'jquery-ui-rails' #ajax拖拽UI,可以直接用鼠标拖拽排序

gem 'ckeditor' #富文本编辑

gem 'ransack' #模糊搜索

gem 'chart-js-rails' #制作图标

gem 'social-share-button'

gem 'ranked-model'
gem 'acts_as_list' #管理员可以在后台自定义列表的现实顺序

gem 'rails-i18n'

gem 'aasm'

gem 'letter_opener' #寄信预览
gem 'premailer-rails' #自动将CSS中转化为inline css

gem 'faker' #产生假资料

gem 'sidekiq' #使用redis数据库的异步处理
gem 'delayed_job' #使用关联式数据库的异步处理

gem 'paranoia' #软删除
gem 'paper_trail' #版本控制

gem 'seo_helper'
gem 'sitemap_generator' #提交sitemap给搜索引擎,让搜索引擎知道网站内有哪些连结,哪些连结是相对重要的。。。

gem 'rubyzip'
gem 'axlsx'
gem 'axlsx_rails' #以xlsx格式汇出Excel文件

效能提升:
gem 'bullet' #侦测效能问题的

部署:
gem 'capistrano'

API:
gem 'rest-client' #可以用Ruby发送http请求

自动化测试:
gem 'rspec-rails' #写测试的
gem 'capybara' #搭配rspec进行feature spec测试
gem 'byebug'

网站安全:
gem 'brakeman' #检测代码漏洞
gem 'bundler-audit' #检查套件有没有漏洞需要升级
gem 'rack-attack' #可以设定当特定IP地址在某一段时间内存取太多次的话,自动封锁
9.用的哪个软件来做需求分析?(问ihower有哪些软件)
任务拆分、用户故事
growthack,landingpage, onboarding
tower线上项目管理软件

13

14.全栈营课程回顾:你都学到了哪些东西?

Ruby基础知识
做了一个招聘网站、一个购物网站
ajax交互式网页
API
rails 自动化测试
数据库基础
代码重构和效能提升
rails网站完全
SEO搜索引擎优化
rails部署

网络基础知识

项目管理:核心是时间管理
growth hack 增长黑客

11.自己平时还学习了哪些编程方面的东西?都浏览哪些网站?
《Ruby基础教程》《Ruby on rails tutorial》《rails guides》
w3schools.com的HTML/CSS/JS/SQL/BOOTSTRAP/JQUERY,
简书、sitepoint上面的文章质量比较高
阮一峰的博客

model views controller 语法解释

Published on:

*【小结】增加controller,就要想要加routes,然后在views里添加路径,然后在controller里把动作补全。
*【小结】增加栏位,修改views和controller,甚至model后,要记得加入params中。

ruby Where is the method 'self' defined in my Rails app

怎么解读这些需求?

购物车练习作业

  • 1、请设计一个功能,可以一键清空购物车内所有的物品
  • 2、某样东西突然不想买了,我可以在购物车内删除它
  • 3、已经加入购物车的物品,不能重复被加入
  • 4、可以更改购物车内购买的数量( 原本预设数量都是1)
  • 5、库存为 0 的货品不能购买
  • 6、在购物车新增数量时,不能更新超过原有库存的数量


1、清空所有物品即要清空格子cart_item,是一个动作,在cart的controller里定义一个新的动作、routes加路径delete :clean。
2、删除一个cart_item,是一个动作,删除一件是destroy的action,所以添加cart_item的controller和相应的destroy的action。
3、商品已加入购物车说明车子id已知。。。加入产品的关键代码是add_products_to_cart。。。
正解:在current_cart.add_product_to_cart(@product)加入判断,当前车子是否包含这件商品if !current_cart.products.include?(@product)
4、商品数量是current_cart.current_item.product.count。。。
正解:更改数量意味着要edit和update数量,商品数量前边有定义cart_item.quantity
5、换个说法是如果库存为0则提示商品无库存,是一个if判断,商品数量是cart_item.quantity,要改的位置有product_controller的add_to_cart行为。
6、更新为cart_item_controller的update行为增加if条件。

怎么解读这些需求?

订单状态切换

  • 1、建立 admin/orders 可以看到系统内所有订单
  • 2、admin 的 order 列表应要能显示订单状态
  • 3、使用者可以“申请取消订单”
  • 4、使用者“申请取消订单”后,管理员应该要收到“申请通知信”
  • 5、后台管理员可以“取消订单”、“出货”
  • 6、后台管理“出货”后,系统应该寄出通知信
  • 7、后台管理员“取消订单”后,系统应该寄出通知信

其他

gem 'letter_opener', group: :development
A:这个gem只在development开发环境下使用

config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost:3000' }  #gem官网没有给这条代码
config.action_mailer.delivery_method = :letter_opener

网址https://fullstack.xinshengdaxue.com/posts/661#task#task是什么?中的
A:#像锚点一样,代表网页中的一个位置,浏览器读取url后会滚动到task所在位置。

Model

观察发现:model的信息是可以在不同名的controller里调用。

查找validates相关用法:https://guides.ruby.tw/rails3/active_record_validations_callbacks.htmlhttps://ruby-china.github.io/rails-guides/active_record_validations.html Active Record 数据验证


validates_presence_of :name
A:validates_presence_of 确定属性是存在的,非空非nil非false。

rails g migration/model,是否是第一次建立就要model?
A:是 
admin_job的controller里没有重新增加title和description栏位(即rails g model title:string description:text),是不是意味着增加的栏位每个controller都可以调用?

A:没错,不管是admin下面的jobs_controller 还是controllers目录下面的,打交道的数据都是同一个job model,因为普通用户和管理员都是对同一个job相关的信息进行操作的。
rails g migration的数据也属于job model吗?或是说,如果我拿新建的admin的controller去调用6-3创建的那些栏位(wage_lower_bound/wage_upper_bound/contact_email)也是可以的?

A:整理自己的理解:"看atom的架构图,model里没有admin_job.rb,因为前后台都是用job.rb,而写进db:migrate的数据因为是add_more_detail_to_job,涉及到job,所以model调用的时候是在job中执行,所以db里的数据相当于是在model/job里。"是的,你这样理解基本是对的。那个后面的to_job,job代表的就是model。所谓的rails 约定优于配置,to_job就是其中的一个例子。
知道11-1,model中只有user和job,不用写关系,但是加入resume就要写,是因为两个就不用多个就要吗?如果resume不写关系会怎样?
A:会提示出错,自己试试,一般model中的rb文件都是要根据所需功能设置关系的。比如,做招聘003的11-2QA,要先找到job,再找相关的resume,如果没有设置相关关系job has_many :resumes,系统就不知道要去哪里找resume。

.xxx的用法在model,跟controller一样是执行动作

```
cart_items.destroy_all
1、destroy_all和delete_all的区别?
A:都用于批量删除表格数据。

delete_all 是一条sql语句删除,它会直接执行删除而不查询数据,优点是网络开销相对少,缺点是如果删除出现问题,回滚起来代价比较大。

destroy_all 则先查出所有的数据,再一条一条的按照主键删除,优点是容易过程出现问题容易终止,缺点是网络开销比较大。

同样的数据量,delete_all 删除的速度更快,因此在什么情况下选用哪种方法,一是可以根据对执行过程的速度需求决定,二是根据对数据安全的需求决定。

代码运行过程参考这里http://blog.csdn.net/feigeswjtu/article/details/51581020
```


current_cart.clean!
A:有加!的要在model进一步定义

Controller

观察发现:xxx_params添加的栏位只是那些在new、update有新增、修改的栏位,而栏位的赋值不用加入,比如product_list一节在订单建立后建立购买明细缓存时,调用栏位没有加入params。

观察发现:左边有带@是controller的参数,右边不带@的是views页面传来的参数。

if !current_user.admin?同理的还有Group.where(:is_hidden => true)
A:①、controller无视db值的属性直接决定游戏动作,!代表"修改为不是"直接决定user不是admin,true决定这个group是隐藏的。
②、数据库admin?默认boolean为false,这样新建的user默认不是admin。db里的值是一种属性,可以在rails c里可以任意改,影响新建时的默认值但是不在controller中起作用。

在index中,params里用:order是因为log日志里有给出参数地址,那么case又是什么意思?
A.固定用法,类似if。不同的是if适用于罗列两种情况,而case用来罗列多种情况。

Q.resume_controller的代码要怎么解读,自己写不出来?
A.第一段,找到要建立resume的那个具体的job(地址栏job/id),在这个job里新建resume页面。
第二段,①先找到具体在哪一个job上(即地址栏里的job/id);②通过筛选的栏位content(在resume_params中过滤)拉到新建立的resume上;③通过@resume.job = @job把job的地址给到新建的resume上,使job和新建的resume关联起来,得到一个具体的新resume的路径;④把当前用户设置成resume用户;


def new
@job = Job.find(params[:job_id])
@resume = Resume.new
end
def create
@job = Job.find(params[:job_id])
@resume = Resume.new(resume_params) #新建resume所以确定了resume的id
@resume.job = @job #@job的参数传给新建resume,即确定job的id
@resume.user = current_user
if @resume.save
flash[:notice] = "成功提交履历"
redirect_to job_path(@job)
else
render :new
end
end

CRUD中Group.new和Group.new(group_params)的区别?
A:Group.new没有数据传送,调用new.html.erb即views的页面。而Group.new(group_params)已经进入new的页面,看链接可以发现这里不涉及id,而是要存储title和description的数据,这两个栏位定义在group_params中,所以是用group_params来调用。

```
1、购物车的逻辑? A:见下方。
def add_to_cart
@product = Product.find(params[:id])
current_cart.add_product_to_cart(@product) #购物车所有动作围绕这句代码在做
redirect_to :back
end

2、什么时候要建model,什么时候要建controller,比如在购物车这里rails g model cart、rails g model cart_item?
A:①、需要新建表单、填表、使用栏位的时候,第一次要建model,后续增加栏位用rails g migration add_栏位to刚刚的model。
②、页面需要执行动作的时候,比如新建表单new、保存表单create、显示出栏位index/show。

3、上述建立的model,什么时候要加栏位,要加多少栏位,比如cart_item加了cart_id、product_id、quantity栏位?
A:建立model都是因为需要建立数据库表单,表单一定是有想要显示的栏位,可以先加最小必要的栏位,主要功能测试成功后再添加其他次要栏位。
```

```
app/models/cart.rb
def add_product_to_cart(product) #定义函数add_product_to_cart(引入参数product)
ci = cart_items.build #新建格子,build与new区别见下一条
ci.product = product #填上所添加商品的id号

ci.quantity = 1 #填上商品数量
ci.save
end

A:ci仅仅是一个参数而已,我们这里需要新建cart_item,并且向里面添加product和quantity,为便于表示把新建的cart_item赋值给ci。变量名称只是为了阅读方便,对代码执行一般没什么影响。
```

```
helper_method :current_cart

def current_cart
@current_cart ||= find_cart
end

private

def find_cart
cart = Cart.find_by(id: session[:cart_id])
if cart.blank?
cart = Cart.create
end
session[:cart_id] = cart.id
return cart
end
end

```

1、helper_method是什么?
A:current_cart 其实原本是一个 controller 内的 method,我们为了要在 view 里面要可以存取它。所以,我们得在 applications_controller.rb 宣告他是 helper_method,才能直接存取。

2、||=是什么?
A:或等于,a ||= b 更像是a || a = b,优先取a,如果a为nil或false则取b。

3、find_by与find的区别?http://jiujiubad-blog.logdown.com/posts/3179266
A:如果查找不到希望找的元素,find会报ActiveRecord::RecordNotFound的错误,而find_by不报错,返回nil。看起來是find只能找id或多个id,find_by 可以找 裡面所有的元素 (title, description, quantity, price)。ruby搜索ruby week ago。

4、(id: session[:cart_id])前面的id:是什么?session[:cart_id]是什么?
A:xxxxxx
在每个人进店时,都会有一块电子感应卡,叫做 session,所以你的电子感应卡上面记录了你拿了哪台车 cart_id,每个人「现在的车」 current_cart 就是透过这样的方式去存取的。————万一你的车丢失了没有关系。if cart.blank? 发现你的车不见了,会再给你一台车。重新登记上去。

5、Cart.create,这里create与build、new有什么区别?
A:①、save:rails中的save其實是create_or_update,新建或修改記錄。

②、new :只是在內存中新建一個對象,操作數據庫要調用save方法。build和new基本相同,多用於一對多情況。

③、create = new + 执行sql。

6、blank?是什么?——空的nil的false的
A:false is blank;阵列[];Hash{};字符(串)''、' '、"\t\n\r"、nil。以上这些都是blank?
如上,一个对象如果是false,空的,或者一个空白字符(串),例如:false, '', ' ', 或者nil,[], {}, 都是blank,所以在 rails c 中输入:


nil.blank? # => true
false.blank? # => true
true.blank? # => false
[].blank? # => true
[1,2,3].blank? # => false
{}.blank? # => true
{ key: 'value' }.blank? # => false
''.blank? # => true
' '.blank? # => true
"\t\n\r".blank? # => true
' blah '.blank? # => false
"\u00a0".blank? # => true
1.blank? # => false
0.blank? # => false
Time.now.blank? # => false

7、present?是什么?——非空非nil非false


def present?
!blank?
end

商品、格子、车子——格子的信息:商品信息id、车子信息id、商品数量

车有很多格子、有很多商品

商品有很多格子

格子属于商品、格子属于车

```
def destroy
@cart = current_cart #当前车子参数传给要执行动作的车子,即拿到车子
@cart_item = @cart.cart_items.find_by(product_id: params[:id]) #拿到商品所在格子
@product = @cart_item.product #格子的商品参数传给要执行动作的商品,即拿到商品
@cart_item.destroy #所有id确定了,删除这个唯一的格子

flash[:warning] = "成功将 #{@product.title} 从购物车删除!"
redirect_to :back

end
end
```

为什么结账页checkout是在cart_controller里用Order.new,能不能是新建一个order的controller做new的action?

order新建后有订单编号为什么不储存订单信息,把商品名称、价格、数量栏位加上去不行吗?为什么还要新建一个product_list的model?

A:一般如果订单已生成,那么商家修改商品价格、库存、描述等,是不能改变已拍下的订单信息的。所以已生成的订单里的商品id用product_list记录,商家商城里的商品id还是用product记录。

```
在订单建立后建立购买明细缓存:
if @order.save
current_cart.cart_items.each do |cart_item|
product_list = ProductList.new

product_list.order = @order

product_list.product_name = cart_item.product.title
product_list.product_price = cart_item.product.price
product_list.quantity = cart_item.quantity
product_list.save
end

A:新建product_list;order参数传给product_list;商品现在的名称、价格、数量分别传给product_list;保存product_list。
```

```
def show
@order = Order.find(params[:id])
@product_lists = @order.product_lists

end

Q:product_lists为什么这里要加s????
A:show的页面order是唯一的用单数,而order里可能有一张或多张订单,要把他们全部show出来就要加s。
```

```
before_create :generate_token

def generate_token
self.token = SecureRandom.uuid
end

def show
@order = Order.find_by_token(params[:id])
@product_lists = @order.product_lists
nd

1、before_create是什么?
A:before_create 是 Rails model 内建的 callbacks,目的是让资料生成储存前先执行某某动作。

2、SecureRandom.uuid是什么?
A:SecureRandom.uuid 是 Ruby 内建的随机生成器。

3、find_by_token是什么?
A:找到元素token
```

```
def index
@orders = current_user.orders
end

1、index中,@orders = current_user.orders与@orders = Order.all的区别?
A:订单order是user的,current_user是一个user,Order.all是指所有user的order。解读成一个user的所有订单、和所有user的所有订单。

```

2、@orders = Order.order("id DESC")和@resumes = @job.resumes.order('created_at DESC'),order前的名次什么情况加s??

```
def pay_with_alipay
@order = Order.find_by_token(params[:id])
@order.set_payment_with!("alipay")
@order.pay!

redirect_to order_path(@order.token), notice: "使用支付宝成功完成付款"

end
```

```
app/models/order.rb
def set_payment_with!(method)
self.update_columns(payment_method: method )
end

def pay!
self.update_columns(is_paid: true )
end
```

1、self.update_columns(payment_method: method )是什么?
A:dash上查到官方文档定义:


def update_column(name, value)
update_columns(name => value)
end

其中,payment_method:相当于是例子中的栏位name,随后的method相当于例子中的value值。

2、self是什么?

A:(不知道)在atom中找不到,dash中rails的没有ruby的有但好像不相关。

3、self.update_columns(is_paid: true ),如果像之前设置is_admin那样写成is_paid行不行?
A:由下面的分析,猜测is_admin是有role_model动态定义,而is_paid没有所以不行(具体用代码测试)。


def define_dynamic_queries(roles)
dynamic_module = Module.new do
roles.each do |role|
["#{role}?".to_sym, "is_#{role}?".to_sym].each do |method|
define_method(method) { is? role }
end
end
end
include dynamic_module
end
原来,role_model根据分配的角色动态地创建方法 - 所以这就是为什么is_admin不在源代码中显示。

```
app/mailers/order_mailer.rb
def notify_order_placed(order)
@order = order
@user = order.user
@product_lists = @order.product_lists

mail(to: @user.email , subject: "[JDstore] 感谢您完成本次的下单,以下是您这次购物明细 #{order.token}")

end
```


OrderMailer.notify_ship(@order).deliver!

```
include AASM #有限状态机的架构

aasm do
state :order_placed, initial: true #已下单
state :paid #已付款
state :shipping #出货中
state :shipped #到货
state :order_cancelled #取消订单
state :good_returned #退货

event :make_payment do  #付款阶段
  transitions from: :order_placed, to: :paid
end

event :ship do  #送货阶段
  transitions from: :paid,         to: :shipping
end

event :deliver do  #收货阶段
  transitions from: :shipping,     to: :shipped
end

event :return_good do  #退货阶段
  transitions from: :shipped,      to: :good_returned
end

event :cancel_order do  #取消订单阶段(已下单、已付款都可以取消)
  transitions from: [:order_placed, :paid], to: :order_cancelled
end

end
```

```
def pay_with_wechat

  • @order.pay!
  • @order.make_payment! redirect_to order_path(@order.token), notice: "使用微信支付成功完成付款" end

app/models/order.rb
event :make_payment, after_commit: :pay! do
transitions from: :order_placed, to: :paid
end

Q:event :make_payment, after_commit: :pay! do是什么?
```

第11章还有很多看不明白的地方,查完这些再过一遍

.xxx的用法在controller


if !current_cart.products.include?(@product)里的.include?

```
if @cart_item.product.quantity >= cart_item_params[:quantity].to_i
@cart_item.update(cart_item_params)
flash[:notice] = "成功变更数量"

1、cart_item_params[:quantity]是什么?

2、.to_i是什么?
```


self.update_columns(is_paid: true ),固定用法前面有解释


OrderMailer.notify_ship(@order).deliver!

Routes

namespace :admin do

resources member do,用于加入/退出群组、是否隐藏、加入购物车、微信支付宝支付
resources collection do,用于?
两者的区别是什么?

member do 和 collection do 的区别?

①、member do自定义对特定元素的action,比如@product。

特定元素的意思就是:生成的url helper,需要带(@pruduct)参数,@product是特定的单一的商品。

例如,用于加入/退出群组、是否隐藏、加入购物车、微信支付宝支付。

②、collection do自定义元素集合的action,比如products。

元素集合的意思就是:生成的url helper,不需要带(@cart)这样的参数,它是对所有的carts做同一操作,而不是对单一个cart操作。

例如,用于清空购物车、购物车结账。


resources :carts do
collection do
delete :clean
post :checkout
end
end


resources :orders do
member do
post :pay_with_alipay
post :pay_with_wechat
post :apply_to_cancel
end
end


resources :orders do
member do
post :cancel
post :ship
post :shipped
post :return
end
end

Views

观察发现:除了index,原来show的页面也是可以调用<% @xxxs.each do |xxx| %>

views里什么时候用(@group),什么时候用(group)?views里的路径,括号里的内容好像变幻莫测,比如product_path(cart_item.product)。
A:①、通常要帶()的話,就是因为要知道是哪个东西要被编辑/浏览/删除,那就会是单数的情况,所以后面基本上就是带 ID 而已。
②、@ 是從 controller 傳進來的,你只要記得這個就好,如果該 controller 下的 action 沒有其他的 @,view 就叫不出來。最簡單的測試,比方說controller 裡面的一個 game 的 action,那會變成:


def game
@nic = "handsome"
end

那你去 game.html.erb 裡面,寫一行 <%= @nic %>,就会看到他把讯息抛出来变成 handsome,你只要写两行就可以测试了。

③、注意观察一下这里是不是在回圈(循环)内,回圈里面一般不用加@,有 @ 这个符号都是 controller 传进来的。你要看整个档案怎么写,不能只看一句,如果他是包在回圈里,那就是回圈生出来的,如果是有@就是controller传进来的

<%= link_to(content_tag(:i, '登入', class: 'fa fa-sign-in'), new_user_session_path) %>
<i class="fa fa-home" ></i>
A:以上都是调用icon的方法,需要安装gem 'font-awesome-rails'
show和edit表单
<%= simple_form_for [:admin, @product] do |f| %>...<%= f.input :title %>...<% end %>
index页面
<tr>
  <th>Name</th>
  <th width="100"> Options</th>
</tr>
<tbody>
<tr>
  <% @products.each do |product| %>
     <td><%= product.title %></td>
     <td><%= link_to("Edit", edit_admin_product_path(product)) %></td>
  <% end %>
</tr>
</tbody>
show页面
<%= @product.title %>
<%= @product.description %>
<%= simple_form_for [@job, @resume] do |f| %>中的[@job,@resume]是什么意思?<%= simple_form_for [:admin, @job] do |f| %>呢?
A:先去找到一个job,再在job里找到resume。
在helper中定义def是前端用的,后端用的在model中定义?
A:Model是用来更数据库打交道的,是在Controller中调用的,Helper是Viewer中拿来用的。初步看起来你这个总结是对的。
views里有时用:method => :delete,有时用method: :delete,那么是不是: xxx =>和:的意思一样(至少debug的时候这些是成对的)?

A:那两种方式意思一样,都可以。
简历数量的路径admin_job_resumes_path(job)是怎么来的?
A:很简单,创建rails g controller admin::job,创建后rake routes就有了。

路径类


<%= form_for cart_item, url: cart_item_path(cart_item.product_id) do |f| %>
A:url对应一个网址;cart_item_path对应的url是:/cart_items/:id(.:format);cart_item.product_id就是这个特定的cart_item的product_id。

图片类

```
<% if @product.image.present? %>
目前商品图

<%= image_tag(@product.image.thumb.url) %>
<% else %>
<%= image_tag("http://placehold.it/200x200&text=No Pic", class: "thumbnail") %>
<% end %>

1、.thumb.url是什么?
A:gem 'carrierwave'中有设置uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200,说明了.thumb.url是指上传并转为200*200的图片。
```

.xxx的用法在views,常表示一种状态而controller中是表示一种动作


<% if current_user.admin? %>views里的.admin?是调用model的吗?


<%= current_cart.products.count %>拿到购物车内的物品数量


<%= order.created_at.to_s(:long) %>


<% if !@order.is_paid? %>,其中is_paid是db的一个栏位设置了boolean。


<%= order.aasm_state %>,其中aasm_state是db的一个栏位。

app/views/carts/index.html.erb 
<% current_cart.cart_items.each do |cart_item| %>  #已在model中定义helper_method
   <%= cart_item.product.title %>
   <%= cart_item.product.price %>
   <%= cart_item.quantity %>
 <% end %>
<% if cart_item.product.price.present? %>,其中present?是什么?
数量选择器quantity的用法:
<%= f.select :quantity, [1,2,3,4,5] %>
<%= f.select :quantity, 1..cart_item.product.quantity %>
  <% case order.aasm_state %>
  <% when "order_placed" %>
    <%= link_to("取消订单",
                cancel_admin_order_path(order),
                class: "btn btn-default btn-sm", method: :post) %>

  <% when "paid" %>
    <%= link_to("取消订单",
                cancel_admin_order_path(order),
                class: "btn btn-default btn-sm", method: :post) %>
    <%= link_to("出货",
                ship_admin_order_path(order),
                class: "btn btn-default btn-sm", method: :post) %>

  <% when "shipping" %>
    <%= link_to("设为已出货",
                shipped_admin_order_path(order),
                class: "btn btn-default btn-sm", method: :post) %>

  <% when "shipped" %>
    <%= link_to("退货",
                return_admin_order_path(order),
                class: "btn btn-default btn-sm", method: :post) %>

  <% when "order_cancelled" %>
    <span class="label label-default">订单已取消</span>

  <% when "good_returned" %>
    <span class="label label-default">已退货</span>

  <% end %>

【转】求职记升级篇——我是如何再次找到工作的 :)趁我还没被再次炒鱿鱼!

Published on:

原文地址:https://forum.qzy.camp/t/topic/1985

全栈营主站 学习中心 帮助文档

求职记升级篇——我是如何再次找到工作的 :)趁我还没被再次炒鱿鱼!

** 面试求职

求职记升级篇——我是如何再次找到工作的 :)趁我还没被再次炒鱿鱼!

** 面试求职

王振华11132

9月23日

**

一、背景介绍
我从2016年10月份决定学习编程,转行做程序员。先是自己在w3schools.com看了两个多月的前端,在codecademy1学习了一些前端课程。然后在12月份报名了全栈营线上第一期,开始学习Ruby on Rails。
我是用上所有时间学习编程的,所以比大部分同学花的时间多。从全栈营的两次魔改大赛投票成绩来看,我只能算很一般,并没有获得过任何奖励,这可能跟我审美差也有关,呵呵...

二、求职过程
2017年4月,学习完求职指南课程之后,Xdite老师在课程中宣布大家可以找工作了,因为我没有获得推荐工作的资格(只有在魔改大赛中前50名才有资格),加上我已经家里蹲了大半年,于是我决定立即行动,开始找工作。
首先是选城市。因为我是光棍一条,来去自由,加上我在拉勾网、boss直聘上的浏览,发现Ruby的工作岗位大部分都在一二线城市,当时我身在南京,于是北上广深杭就成了我的目标,先去最近的杭州。
简历我投了估计有50家以上,哈哈,但其中一多半对方连看都没看过,还有很多只是看看没有回复,哈哈。正式的面试、笔试我一共经历了七次,最终有三家通过,共历时2个月。

以上是我第一次找工作的过程,我到上海工作不到两个月,公司业务出现问题,不需要人了,于是我就被炒鱿鱼了,~~(>_<)~~,于是在8月份我又要重新找工作了。
我先是把几本书重新仔细看了一遍,对简历做了一点修改(主要是把自己看过的书写上去了,具体是哪些书,后面会说到)然后继续投简历,面试,又用了近两个月的时间,才于前几天刚刚入职。
趁着还没被再次炒鱿鱼,

,把最近这段时间的感悟总结出来,供大家拍砖。

三、经验之谈,仅供参考

1.除了学好全栈营的课程外,要求职还需要补充学习的:
我们全栈营的课程当然是非常好的,但经过两次面试之后,我就意识到这些问题:
1)全栈营更重视实战,对理论知识的讲解并不多。但求职时如果是面试,大多会问到很多理论知识(当然,也要少数公司不喜欢问理论问题,而是直接给你个项目让你做)。面试过几次之后,你就会发现,很多面试题目出现的频率很高,好多公司都会问到。比如:rails的特点/指导思想是什么?你用过哪些gem? 我遇到的面试题目,我都整理在求职面试题目整理11 中了。

2)全栈营培训的是Ruby on Rails,因为注重实战,所以更偏向Rails,所以Ruby的知识相对而言就有所欠缺。《Ruby基础教程》(第四版),是最最基础的Ruby知识和编程知识,适合现阶段的同学们,尤其适合转行的同学,书中前半部分讲解了很多编程的基础知识如变量、数据类型、控制结构等。我一开始买了《Ruby元编程》,硬着头皮看,但看得云里雾里,后来经ihower老师推荐了这本基础教程。
3)自己做过的项目中,较为复杂的部分一定要能说清它的逻辑,比如购物网站的购物车是如何实现的。这种问题并不需要你把所有代码、细节背的滚瓜烂熟,只需要你能说清楚其中的逻辑和关键细节。相关问题我也整理在求职面试题目整理11中了。

Ruby on Rails Guides5这个大部分同学在学习的过程中应该都看过其中的一部分了,但我建议如果时间允许,还是要尽可能把我们已经学习到的、涉及到的部分看一遍,或者说把我们现在能看懂的部分看一遍,也是对rails知识的梳理。至少要从总体上知道rails需要掌握的知识包括哪些部分,他们的从属关系是怎样的,遇到问题后知道去哪一部分查找。其实这个是有中文版本的,可以到Rubychina论坛购买中文版电子书(不要报告老师哈,我最近才发现的,哈哈,老师是鼓励我们用英文,但江湖救急吗,并且我个人觉得这个翻译质量还过得去)
我也建议全栈营对要求职的同学能有更多额外的指导,比如提早让要求职的同学去补充Ruby基础知识。个人的一点感受,哈哈。

《Ruby on rails tutorial》2个人感觉这本书非常好,整本书从头到尾是一个类似Twitter的项目开发,并且随时进行详细的讲解,告诉你背后的理论知识,而且是TDD(不知道TDD是什么的面壁:)的。

2.做好长期艰苦战斗的准备,不要太挑剔第一份工作
如果你之前就是个程序员,又从全栈营毕业了,那找个ruby工程师的工作可能易如反掌。因为有些公司的招聘要求中甚至会是:其他语言想转Ruby也可,只要学习能力足够强,愿意向Ruby领域发展的。也就是说,你即使以前毫无Ruby经验,只要之前就是个成熟的程序员,这些公司允许你进去后边学边用。
如果你大学是学习计算机相关专业的,那找工作可能也会容易很多。因为你用很多计算机基础知识,提到什么你都懂一些。
如果你刚刚大学毕业,那年轻也至少是个优势。不像我这种已经28岁高龄,即将步入中年的人,

,投实习岗位人家都会很委婉地回复:对不起,我们的实习岗位只招应届毕业生。
有同学可能会反驳说,这些很多时候都不是硬性规定啊,很多都是可以突破的呀,转行有转行的优势呀,年龄大一点难道就毫无机会了吗?
你说的都对,
,我也并不是要打击大家的积极性,我从来也不反对转行,我说这些只是想让那些犹豫是否要转行做程序员的同学做好心理准备。

如果以上条件你都不满足,那么恭喜你,你和我一样,

,要做好长期艰苦作战的准备了。不要以为轻轻松松地三五天就能找到工作,更不要以为各个公司都抢着收你。比较大的可能是:你投的大多数建立根本不会收到回复,回复大部分都是“不合适”,你可能只能得到很少的几次面试机会,并且大部分面试都不会通过。所以,整个求职过程中会有长期的、反复的、深深的挫败感,被拒几次之后,心里面的感觉就是————慌了。对自己还能不能找到工作表示怀疑~~(>_<)~~。
当然,以上只是我个人的经历、感受,并不代表所有人(有可能是我在全栈营学的不够好,有可能是我简历写的不够好,有可能是我面试能力不强。希望大家运用批判性思考来看我这篇文章,用力拍砖
),但这的确是我个人真实的感受。当然还有一个重要原因是,我在最近半年里两次找工作,每次都长达两个月,我不是在找工作,就是在找工作的路上,
。尤其是后面这次找工作,也就是最近一个月来,投简历和面试,到后来我不仅是挫败,甚至感到很疲倦,完全没有心情再继续学下去了,基本是在死撑,

说这些并不是为了吓唬谁,只是我自己经历这些的时候,的确感到慌张、无助,不知道该怎么办,所以分享出来与大家做个交流。求职过程中很容易怀疑自己是不是学的不够认真(但我明明学的听认真的呀!),心里埋怨那些公司为什么要求那么高,为什么不能给新人一个机会?
但反过来想想,其实那些公司的做法又很正常。谁不想招个进来就能上手的?谁想招个遇到问题就要来问你的人?我上个月在投了几份简历被拒之后,决心从头开始写个厉害的网站给他们瞧瞧,结果是写不出来
。我发现这才是我现在真是的水平:看网上简单的项目教程感觉很无聊,大部分自己都会了;但自己想从头开始写个复杂一些的项目,又异常艰难。以我这样的水平找工作,求职过程艰难我觉得也很正常

那我好像毫无优势、毫无希望啊,可我最终又为什么能找到工作呢?
1)不用考虑地域:我现在光棍一条,去哪里工作都差不多,这就是我的一大优势。
2)不过分重视薪水:以我个人现在的水平,我觉得北上广深杭能拿到8k,武汉、长沙等城市再略微降低一些,是比较合适的。
3)不要太要脸:

。一开始投简历的时候,我看了下照片网站后,发现大部分都至少要一年以上工作经验,那我基本都不符合,这怎么办呢?而现在我的做法是,只要招聘要求中没有明确说明招聘的是“资深、高级”工程师,只要薪水没有高到能砸死我的程度,我就不要脸地把简历投过去。因为工作年限这个东西本来就不是死的,不是硬性要求,有些人工作十年可能只是把第一年的工作重复了十遍而已,你把简历投过去也许就能得到面试机会。退一步讲,即使得不到面试机会或者面试没通过,那又如何呢?你有多大的损失吗?并没有!你至少增加了面试经验。所以这基本是个只赚不赔的买卖。有些同学可能会说,如果面试地点在其他城市怎么办?我为了一个面试要跑那么远,既费时间又费钱。我的做法是:其他城市的面试,我尽量要求先进行远程面试。我的理由通常是:“我过去一趟也不容易,最好能先远程简单面试一下,如果感觉大致差不多,我再过去进一步面试也可以。”很多公司都会同意的。
4)不太挑剔公司:不论你是创业公司还是外包公司,不论你的办公环境高大上还是接地气,这些都不重要,至少对现在的我来说都不是最重要的。
5)打持久战,越挫越强:我知道多次被拒后你会很慌张,你会很受伤,你会怀疑自己。但没有别的解决办法,你必须做到越挫越强,自己给自己加油。你要知道,即使一部分面试官对培训班出身的程序员有偏见,那还有另一部分呢!总会有人愿意招收你的,只是时间问题!你要做的就是坚持下去。
“庸人一挫就怕,才胜便骄,千古一辙。”我在高中时接触到这句话,当时并没有多么深的理解。但最近的经历让我感受到,自己现在是个如假包换的庸人
, 受到一点挫折就害怕、怀疑自己、失去信心、觉得自己智力有问题,编程遇到个bug一时解决不了就垂头丧气;取得一点点成绩就开始骄傲了,就觉得自己无所不能了。这句话放在这里,与诸君共勉,愿我们终有一天,不再是个庸人:)
6)运气:你真的有可能会碰到贵人,并不会问你太多问题,只是简单聊聊,就说可以招你进公司了。因为每个公司的需求不同,每个面试官对待新人的心态也不同。但要想有这样的好运气,你要能坚持地足够久,你要多投简历。还要,不要在原地等运气来,不要因为有可能有运气就不学习了,你只有努力学习,至少让面试官看到你有良好的学习态度,有学习能力,他才能给你这个新人机会。

3. 把面试的过程当做学习的好机会
我们经历了全栈营几个月的学习后,可能很多人不知道自己下一步的学习方向了,求职正好可以给你指出方向。面试时可以自己准备纸笔,在回答问题的时候也尽量把问题记录下来,回来后进行整理、总结,并以此指导自己下一步的学习。这样经过几次面试,你就会功力大增。

4. 投简历的频率
求职指南课程中告诫我们不要一下就把简历都投完了,要慢慢投。这本身是对的。但我个人认为,这个频率只能你自己去摸索、把握。
如果你投的简历大多数都有回复,大多数都有面试机会,那当然要慢慢投,防止面试都集中在一起。但如果像我这样,投出的简历大都没有回复,那就只能投的多一些了。
所以,我认为正确的做法是:一开始先慢慢投,少投几个,过几天看看反应如何,再决定后面投简历的频率。

5.每次面试前都要留出时间做充分的准备
尽量不要把多次面试安排在一起,而是分开。因为每经过一次面试,你回去后查漏补缺后,就会功力大增。我每次接到面试通知,都是”额,不好意思,我这几天有点事情,面试能不能安排到。。。。。。。。。哈哈,都是套路”。尽量做到在每次面试前,都能有几天时间来做准备。
之所以每次面试前都要留出几天时间来做准备,我个人觉得主要是为了背理论知识。有同学可能会说,编程这种理工科的东西怎么能靠死记硬背呢?
我们已经算入门Ruby了,能理解的东西当然要努力去理解了。但以我个人的观点,有些东西我们现阶段是无法彻底理解的。之所以无法理解,一个重要的原因就是还从未用到过。这样的理论知识我个人基本是看了就忘,所以我每次面试前都会把这些理论知识再回顾一遍,这几个月里我已经输不起回顾过多少遍了

。只要你在面试前回顾一遍,面试中问到相关的问题你就能对答如流

6.不下水是很难学会游泳的,除了笑来老师
说了那么多,你自己不去投简历、面试,只是站在一边看也没用,不下水是很难学会游泳的,笑来老师除外(笑来老师在一篇文章中提到,他站在岸上,仅靠说,就教会了罗永浩同学游泳

神人)
慎思断行:做决定之前尽可能手机信息,做好心理准备,做出明智的决策。一旦决定了(比如决定转行做程序员),就坚定地执行下去。

我们绝大部分同学之前都不是程序员,在求职过程中难免会遇到各种问题。一个人求职太孤独,不如大家一起结伴打怪。
我建了个微信群,大家可以在这个群里相互交流职位信息、简历投递技巧、面试经验,面试、笔试题目。大家相互帮助,找到合适的工作。
如果扫码无效,可以加我个人微信:185 5166 4870, 注明求职,我会拉你进群。

sK9viOUoTCmEMdyowDMf_IMG_0025.JPG602x800

14 赞****回复

** 收藏 ** 分享 ** 标记 ** 邀请 ** 回复**跟踪因为你阅读了该主题,你将会收到通知。

推荐主题

主题 分类 回复 浏览 活动
建立seed档,保存原始数据。(请补充) 1 Rails 第三课 13 494 10月26日
**【教程】在mac上配置快捷命令,只需3个步骤 1 Mac/OSX/软件 3 417 10月25日
**【分享】搜索与排序(简易ransack搜索) 2 Joblisting魔改大赛 13 835 9月12日
Intercom客服系统傻瓜教程 12 共同成长 21 860 8月17日
一个教程搞定navbar悬浮和footer固定问题–详细到没朋友的教程 4 1 ** Rails 实战:招聘网站 21 332 8月7日

还有 52 个未读主题 可以阅读,或者浏览** 面试求职中的其他主题

git fetch与git pull的区别

Published on:

原文网址:http://dumpling001-blog.logdown.com/posts/1839660

网上一篇文章这样介绍git fetch

“git fetch”命令执行完毕之后,还不会立即将下载的文件合并到你当前工作目录里,这就给你了一个选择下一步操作的机会,要是想将从远程分支下载的文件更新到你的工作目录里,你需要执行一个“合并(merge)”操作。例如,我当前的本地分支为”master“(执行git checkout master后),这时我想执行合并操作:

git merge origin/master

如果你只是想看看本地分支和远程分支的差异,你可以使用下面的命令:

git diff master origin/master

单独进行下载和合并是一个好的做法,你可以先看看下载的是什么,然后再决定是否和本地代码合并。而且分开来做,可以清晰的区别开本地分支和远程分支,方便选择使用。

作者建议:

“不要用git pull,用git fetch和git merge代替它。”

git pull的问题是它把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。

将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。当然,除非你关闭所有的安全选项,否则git pull在你本地工作目录还不至于造成不可挽回的损失,但很多时候我们宁愿做的慢一些,也不愿意返工重来。

阮一峰写的《Git远程操作详解》这样介绍:

一旦远程主机的版本库有了更新(Git术语叫做commit),需要将这些更新取回本地,这时就要用到git fetch命令。

$ git fetch <远程主机名>

上面命令将某个远程主机的更新,全部取回本地。

git fetch命令通常用来查看其他人的进程,因为它取回的代码对你本地的开发代码没有影响。

默认情况下,git fetch取回所有分支(branch)的更新。如果只想取回特定分支的更新,可以指定分支名。

$ git fetch <远程主机名> <分支名>

比如,取回origin主机的master分支。

$ git fetch origin master

所取回的更新,在本地主机上要用"远程主机名/分支名"的形式读取。比如origin主机的master,就要用origin/master读取。

google精准度 查单词 语言设置

Published on:

原文出处:http://dumpling001-blog.logdown.com/posts/1821641

向Anndo同学请教后,才发现Google的语言设置太重要了!

我开始查thumbnail没有出现google翻译:

Anndo说她用的就是Google,把单词扔进去,google就会跑出一个解释;我感到很奇怪,因为我就是这么干的,结果第一个搜索结果是爱词霸,看到她的截图后我终于明白了:

是语言的问题!

是语言的问题!

是语言的问题!

火速改语言设置:

出来的结果:

帅呆了有木有?!

同时也痛哭从前被中文google不知不觉中被误导了大概有千百回吧!

Anndo还说,对单词不用花太多心思,会意即可。

浏览器语言设置的改变是个根本性的改变,查询精准度高出很多。

find_by和find的区别

Published on:

教材5-4 Step 3: 购物车设计 Part 2有一段:

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

 # ...略



+  helper_method :current_cart

+  def current_cart
+    @current_cart ||= find_cart
+  end

+  private

+  def find_cart
+    cart = Cart.find_by(id: session[:cart_id])
+    if cart.blank?
+      cart = Cart.create
+    end
+    session[:cart_id] = cart.id
+    return cart
+  end
end

这里面的一句:cart = Cart.find_by(id: session[:cart_id])中的find_by不太好理解。那如何了解find_by呢?find_by与find又有什么区别呢?

首先,找到它们的定义,在Dash(一个app)中搜索find和find_by:

看了之后觉得不太好理解,那就在rails c里实际操作一下吧!

我做的练习里有Cart这个元素,先Cart.all看看有什么东东:

可以看到只有2个cart,再用cart测试下find函数,在测试find之前,先用我们最熟悉的.first试试看:

测试结果显示:Cart.find(1),Cart.find(2),都可以查到相应id的cart;id=3的cart不存在,于是报ActiveRecord::RecordNotFound的错误。

同样的用find_by试试是什么效果:

没有报错,只是返回nil。

那这就是find和find_by的一个区别了:如果查找不到希望找的元素,find会报ActiveRecord::RecordNotFound的错误,而find_by不报错,返回nil。

网上还介绍了一种用法:
Product.find_by(title: 'the yellow book’)

我们也来试试看:

报错了!什么原因?因为title是Product的字段,而不是Cart的字段。

先看看Product.all,果然有title:

那就用Product来测试吧!

这下OK了!

还有一种写法哦!

看看find_by这么厉害,其实find也很厉害:它可以同时搜索多个指定id的特定元素:

如果觉得这里面的rails c显示的代码很乱,可以在Gemfile里安装一个gem 'awesome_rails_console' ,安装后bundle install,这样显示就清爽多了有木有:

Tim Chang6个月前

看起來是 find 只能找id
find_by 可以找 裡面所有的元素 (title, description, quantity, price)

** **•回复分享 ›

刘华佼 管理员 ** Tim Chang6个月前

Dash上找到的:
find的用法:
Person.find(1) # returns the object for ID = 1
Person.find("1") # returns the object for ID = 1
Person.find("31-sarah") # returns the object for ID = 31
Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
Person.find([1]) # returns an array for the object with ID = 1
Person.where("administrator = 1").order("created_on DESC").find(1)

find_by的用法:
Post.find_by name: 'Spartacus', rating: 4
Post.find_by "published_at < ?", 2.weeks.ago

看起来你说的是对的,Person.find("31-sarah"),rating: 4,2.weeks.ago 就是这些不太明白,但不是高频小套路就不用care了。

** **•回复分享 ›

  • 刘华佼 管理员 ** 刘华佼6个月前

    附上Nic老师的回答:

    1)
    31-sarah,这是找某笔数据吧,不代表任何意义
    rating: 4 ,只是他想要找这个 table 里面的 rating 栏位,数值是4而已
    2.weeks.ago,直接翻中文就知道意思了,这个是 ruby 的用法,可以查询 ruby week ago 搜看看 google

    ** **•回复分享 ›

购物网站逐一击破code

Published on:

刘华佼dumpling001

5月18日

**

5-10 rails中的"member do" and "collection do"

dumpling001-blog.logdown.com14

5-10 rails中的"member do" and "collection do" « 刘华佼的全栈学习记录

config/routes.rb中的member do 和collection do的主要区别是: 如果需要自定义对元素成员的action,需要用到成员路由member do; 如果需要自定义...

<i class="..."></i>

dumpling001-blog.logdown.com8

5-10 是什么东东 « 刘华佼的全栈学习记录

使用Icon的方法之一就是用 tag。 在

里包含CDN(内容分发网络)的Icon库;如: href="https://cdnjs.cloudflare.com/ajax/li...

dumpling001-blog.logdown.com4

5-10 helper_method是什么东东? « 刘华佼的全栈学习记录

教材5-4 Step 3: 购物车设计 Part 2里有出现一句helper_method :current_cart: class ApplicationController < Actio...

dumpling001-blog.logdown.com2

5-10 "||="是什么东东? « 刘华佼的全栈学习记录

教材5-4 Step 3: 购物车设计 Part 2中说: a ||= b 等于 a = a || b。意思是如果 a 是 nil 的话。 a 会被赋予 b 值。 …… 所以 def c...

dumpling001-blog.logdown.com3

5-11 如何了解Ruby on Rails中,find与find_by的区别? « 刘华佼的全栈学习记录

教材5-4 Step 3: 购物车设计 Part 2有一段: app/controllers/application_controller.rb class ApplicationContro...

dumpling001-blog.logdown.com3

5-11 blank?是什么东东 « 刘华佼的全栈学习记录

在dash上搜索blank 出现了文档rails/activesupport/lib/active_support/core_ext/object/blank.rb: 往上翻阅: cl...

dumpling001-blog.logdown.com1

5-11 present?是什么东东 « 刘华佼的全栈学习记录

在dash上搜索present 出现了文档rails/activesupport/lib/active_support/core_ext/object/blank.rb: def p...

dumpling001-blog.logdown.com4

5-11 thumb.url是什么东东 « 刘华佼的全栈学习记录

答案在这里CarrierWave $ brew install imagemagick class MyUploader < CarrierWave::Uploader::Base inc...

dumpling001-blog.logdown.com3

5-11 661#task是什么东东? « 刘华佼的全栈学习记录

郭同学的问题: https://fullstack.xinshengdaxue.com/posts/661,这个打开,点击【提交作业】按钮后进入作业页面,即下面的链接 https://ful...

dumpling001-blog.logdown.com6

5-12 thumbnail是什么?& 英语词典很重要 & Google 语言设置更重要 « 刘华佼的全栈学习记录

对比下Google翻译、海词、剑桥词典、Mac自带词典和爱词霸: 我首先查的是爱词霸,翻译是“拇指指甲”,我被弄糊涂了,于是继续查,去技术帖子上查:例如: Create thumb...

dumpling001-blog.logdown.com7

5-12 clearfix是什么东东? « 刘华佼的全栈学习记录

这篇讲的很清楚: What is a clearfix? 还有人推荐讲解视频,在第8分钟左右讲clearfix: all about floats screencast 用一张图说明cl...

dumpling001-blog.logdown.com2

5-13 new和build真的有区别吗? « 刘华佼的全栈学习记录

stackoverflow的在2011年的帖子Build vs new in Rails 3说了new和build的区别: The only difference between some_...

dumpling001-blog.logdown.com3

5-13 url: cart_item_path(cart_item.product_id)是什么意思? « 刘华佼的全栈学习记录

1、拆分 想了解整句的意思,先分拆成 url cart_item_path cart_item.product_id 2、逐一破解2.1 url url即统一资源定位符Uniform Re...

dumpling001-blog.logdown.com8

5-15 git fetch与git pull 的区别 « 刘华佼的全栈学习记录

网上一篇文章这样介绍git fetch: “git fetch”命令执行完毕之后,还不会立即将下载的文件合并到你当前工作目录里,这就给你了一个选择下一步操作的机会,要是想将从远程分支下载的文...

dumpling001-blog.logdown.com5

5-18 给iTerm2换个漂亮的皮肤(主题) « 刘华佼的全栈学习记录

某天不想学习了,就想着调下iTerm的主题吧!顺便调节下心情! 在此之前请确保阅读并按下面帮助文档操作过: 调配Terminal为zsh与安装oh-my-zsh iterm2 的配置新手补...

typora怎么打出 input yaml front matter

Published on:

Typora 支持YAML Front Matter。输入---在文章的顶端然后按下Enter键就会采用或者从菜单中插入一个元数据块。

```+回车,多行代码