over 2 years ago

重點:9.3:seed the database(9.3.2:faker) + paginate(9.3.3:will_paginate + bootstrap-will_paginate)。
重點:9.4.1:設成boolean,就會自動有?的method。 要記得把boolean的預設值設定為default: false

  1. authentication :allows us to identify users of our site: 成為用戶。需要登入才能看見的頁面,會將網友導到登入頁。9.2.1
  2. authorization :lets us control what they can do:用戶可以做些什麼。非經授權可以瀏覽的頁面,將會被導到首頁。9.2.2
  3. 防止未登入的網友看網頁:before_action(是before filters的一種)在controller所有的actions執行前會先執行。 Before filters use the before_action command to arrange for a particular method to be called before the given actions3 To require users to be logged in, we define alogged_in_user method and invoke it using before_action :logged_in_user, as shown in Listing 9.12.
    app/controllers/users_controller.rb
    class UsersController < ApplicationController
    before_action :logged_in_user, only: [:edit, :update]
    private
    def user_params
    params.require(:user).permit(:name, :email, :password,:password_confirmation)
    end
    # Before filters
    
    # Confirms a logged-in user.
    
    def logged_in_user
    unless logged_in?
    flash[:danger] = "Please log in."
    redirect_to login_url
    end
    end
    end
    
  4. 9.2.1 要登入才能看到某些頁面:logged_in_user
    預設值是只要有before filters,在該controller內的每個action執行之前,都會先執行before filters,除非我們先設定好only這個hash。before_action :logged_in_user, only: [:edit, :update]
    By default, before filters apply to every action in a controller, so here we restrict the filter to act only on the :edit and :update actions by passing the appropriate :only options hash.

  5. 9.2.2 用戶只能看到自己頁面:correct_user
    users should only be allowed to edit their own information.

  6. 設定可以訪問該頁面的正確使用者correct_user

    app/controllers/users_controller.rb
    class UsersController < ApplicationController
    before_action :logged_in_user, only: [:edit, :update]
    before_action :correct_user,   only: [:edit, :update]
    def edit
    end
    def update
    if @user.update_attributes(user_params)
    flash[:success] = "Profile updated"
    redirect_to @user
    else
    render 'edit'
    end
    end
    private
    # Confirms the correct user.
    
    def correct_user
    @user = User.find(params[:id])
    redirect_to(root_url) unless @user == current_user
    end
    end
    
  7. unless @user == current_user可以變成unless current_user?(@user)

    app/helpers/sessions_helper.rb
    def current_user?(user)
    user == current_user
    end
    
  8. 當用戶訪問edit頁面的時候,會先跑before_actioncorrect_user會先抓出來@user,接著跑current_user?(@user)的時候,會把@user送到sessions_helper.rbcurrent_user?(user)去,如果user == current_user是正確的,current_user?(user)會傳true回去correct_user,然後該用戶就可以進去edit page

  9. 9.2.3 Friendly forwarding:登入後,會把用戶轉到用戶本來想要去的頁面。
    要把本來要去的頁面先存在store_location裡面
    In order to forward users to their intended destination, we need to store the location of the requested page somewhere, and then redirect to that location instead of to the default. We accomplish this with a pair of methods, store_location and redirect_back_or, both defined in the Sessions helper (Listing 9.27).

    app/helpers/sessions_helper.rb
    module SessionsHelper
    # Redirects to stored location (or to the default).
    
    def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
    end
    # Stores the URL trying to be accessed.
    
    def store_location
    session[:forwarding_url] = request.url if request.get?
    end
    end
    

    這邊將使用session。按照8.2.1的解釋:Session是Rails內建的方法,session[:user_id] = user.id,這種方式可以把id加密,然後把session[:user_id]存在瀏覽器裡面,以後就可以存取。
    所以session[:forwarding_url] = request.url,也是相同的步驟:將所要求的網址存到session裡面去。
    最後,要把store_location放到logged_in_user method裡面去:如果沒有logged in,會先儲存本來要去的地方在session,然後顯示請登入的訊息,接著轉到登入頁面去。

    app/controllers/users_controller.rb
    def logged_in_user
    unless logged_in?
    store_location
    flash[:danger] = "Please log in."
    redirect_to login_url
    end
    end
    
  10. redirect_back_or(default)method放到sessions_controller.rbcreate去。

    app/controllers/sessions_controller.rb
    def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      redirect_back_or user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
    end
    
  11. 9.3:seed the database(9.3.2:faker) + paginate(9.3.3:will_paginate + bootstrap-will_paginate)

  12. 用faker gem來新增假用戶 (灌完gem之後,記得要bundle install),清空資料庫 (reset the database:bundle exec rake db:migrate:reset)和重啟資料庫(invoke the Rake task using db:seed =>bundle exec rake db:seed)

  13. create!會在有錯誤的時後跳出例外(exception:主要是為了debug)。
    The create! method is just like the create method, except it raises an exception (Section 6.1.4) for an invalid user rather than returning false. This behavior makes debugging easier by avoiding silent errors.
    參考:save 與 save! / create 與 create!

    其中 save / create,遇到過 validation 時,只會回傳 true 或 false。但有時候我們要 debug 一個表單,有時候一直不知道為何表單為何沒成功一直 false,有時候會使用 save! 或 create! 去 debug。這兩個 method 會 throw ActiveRecord::RecordInvalid exception 中斷程式。明確的告訴你壞在哪邊。

  14. 9.3.3:will_paginate + bootstrap-will_paginate

  15. 在user的view時,will_paginate會自動找尋@user (在不同的view應該是會找不同的@)@users = User.paginate(page: params[:page])
    The will_paginate method is a little magical; inside a users view, it automatically looks for an @users object, and then displays pagination links to access other pages.

  16. 9.4.1:設成boolean,就會自動有?的method。 要記得把boolean的預設值設定為default: false
    We will identify privileged administrative users with a boolean admin attribute in the User model, which will lead automatically to an admin? boolean method to test for admin status. The resulting data model appears in Figure 9.14.

← 新增PROFILE: view/dashboard/profile/new.html.erb ROR TUTORIAL (3RD ED.) Ch10 Account activation and password reset →