2016/11/3

今天做了什么?

①作业提交后能显示已提交。(最后也没能做出来,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(调用coursepaid_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:droprake db:createrake 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)