今天做了什么?
①作业提交后能显示已提交。(最后也没能做出来,Rebecca做出来了)
②理清所有与恭喜页面有关的流程,新增页面,调整逻辑。
③处理完成登录系统。包括登录、注册、退出的相关流程。
④在做功能的时候,因为各种原因(包括自己操作不当、之前在处理ontrack代码绕过的一些问题重新浮现等等)出现了各种坑,在老师帮助下勉强弄清了与登录、session、csrf有关的一些东西。
今天学到了什么?
①理解一下has_many/belongs_to和栏位的一些关系
比如post belongs_to course,如果要存course的id,则还要在post 这个model 里面建一个course_id的栏位。(注:没有建立user_id是因为devise这个gem自带了current_user可以直接使用)
如果在controller里面post要调用course的话,其实是要先通过post.course调用course_id,进而在调用course的其他栏位。比如:
@course = @post.course(调用course_id)
if @course.paid_courses(调用course里paid_courses的栏位)
②新思路:要对数据库传入资料或更改不一定要新建一个action或者通过按钮的点击实现功能。也可以放在原来的action,比如create,update里面也可以,这样就是只要实行了create或者update这个动作,就是做了某个model里面def的东西。
③一个栏位只能存储一个值!!!
多对多关系的原因是:一个栏位只能有一个值。
比如:user_id (1) post_id(1,2,3)
错误思路:在user的model 里面建立一个post_id 的栏位,里面传进去post_id(1,2,3)
正确思路:新建一个post_relationship 的model,里面包含user_id和post_id两个栏位,这样里面就可以这样存储:user_id(1) post_id(1),user_id(1) post_id(2),user_id(1) post_id(2)
所以要思考的是用何种方式把数据存进数据库里,即如何告诉数据库我们要存什么。
④clone专案必须用和之前不一样的文件名
删除专案后,重新clone或者建立一个相同文件名的专案会出现这样的错误。
建一个不同文件名的专案即可解决。
⑤一般来说,clone一个新专案后需要运行的代码整理
bundle install
bundle update
rake db:create
rake db:migrate
rake db:seed
⑥新clone下来的专案(quanzhan)出现登录不进去或者退出不了的情况(数据传不进去)
原因:
原来ontrack的设计是有很多的team,每个team对应一个domain。每次登陆时,只要是同一个team,就是同一个domain,同一个csrf,这时devise就会顺利通过。而现在我们把team拔掉了,所以不需要domain来实现这个功能。
这个时候,如果domain还在的话,csrf则会每次都判断为不同人进入(csrf是从session来判断的),所以devise会将这种情况判定为非法登入,则会阻止登陆。
解决办法:
- 去掉config/initializers/session_store.rb里面的
domain: ENV.fetch("SESSION_STORE_DOMAIN", ENV.fetch("APPLICATION_HOST"))
原因:
Rails.application.config.session_store(
:cookie_store, :cookie_store,
key: "quanzhan_session", key: "quanzhan_session",
domain: ENV.fetch("SESSIONSTORE_DOMAIN", ENV.fetch("APPLICATIONHOST")),
tld_length: 2 tld_length: 2
) )
session_store.rb 里面没有 SESSIONSTORE_DOMAIN
所以 cookie 吃的是 .quanzhan.dev 而不是 quanzhan.dev
因此在奇怪的情形下,会同时存在两个 cookie
一个叫 .quanzhan.dev 与 quanzhan.dev
浏览器分不清楚谁是谁,所以根本登不进去。
解决的方法就是把 SESSIONSTORE_DOMAIN 干掉
并且清除浏览器的 cookie 就回复正常了
⑦网页运行的时候, rake db:drop
是会失败的,因为网页还在运行原有的数据库,所以需要先 powder down
关掉powder(或者退出rails s
),再 rake db:drop
,rake db:create
,rake db:migrate
,然后再powder up
。
⑧用count的思路可以解决作业提交后能显示已提交这个问题。作业提交后显示已提交,可以拆解为判断所有answer提交后显示某个东西。
思路:读取到answer记为0,否则记为1。然后判断sum>0即为作业未完成,else则为作业已完成。
这种思路可以解决类似于需要计数的一些典型问题。
实现代码:
<% if post.tasks_count > 0 %>
<% sum = 0 %>
<% post.tasks.each do |task| %>
<% if current_user.has_submitted_answer?(task) %>
<% unsubmit = 0 %>
<% else %>
<% unsubmit = 1 %>
<% end %>
<% sum = sum + unsubmit %>
<% end %>
<% if sum > 0 %>
<%= ibutton("做作业", post_path(post), :class => "pull-left btn btn-default btn-sm", :iclass => "fa fa-coffee") %>
<% else %>
<%= ibutton("已提交", post_path(post), :class => "pull-left btn btn-default btn-sm", :iclass => "fa fa-check") %>
<% end %>
<% end %>
def has_submitted_answer?(task)
task.answers.where(user: self).first
end
⑨怎样用新的自己建立的controller替代devise默认的controller:
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
# build_resource(sign_up_params)
super
end
def edit
super
end
private
def sign_up_params
params.require(:user).permit(:username, :email, :password, :password_confirmation)
end
def after_update_path_for(resource)
account_users_path
end
def after_sign_up_path_for(resource)
account_congratulations_path
end
end
private下面可以设置各种转态的跳转。
⑩git stash
如果遇到自己在某分支上做了很多工作,但是想要把这些工作抛在一个新分支去,可以这样做:
先git stash
把所做的修改先放在一个贮藏处,这时候git status
可以看到没做修改。然后新建一个分支,运行git stash apply
把内容拉过来即可。
⑪route写法区别
get "account/congratulations/after_pay", to: "account/congratulations#after_pay"
namespace :accont do
resources :congratulations do
member do
post :after_pay
end
end
end
上面的写法导出的链接是account/congratulations/after_pay
,下面则是account/congratulations/:id/after_pay
小技巧
很多gem里面有很多的wiki,里面有很多常见问题的解答,如果遇到问题可以到里面去看看。
How To: redirect to a specific page on successful sign in
How To: Redirect to a specific page on successful sign up (registration)