Action Controller Overview(2)

Strong Parameters
Strong parameter為Rail4之後內建的一種安全機制,避免有心人士在填資料時,偷塞參數,惡搞資料庫,輕則資料被刪除竄改,重則資料外洩,造成安全問題。
參考資料
http://springok-blog.logdown.com/posts/2015/11/19/strong-parameter

class PeopleController < ActionController::Base
  def create
    Person.create(params[:person])
  end

  def update
    person = current_account.people.find(params[:id])
    person.update!(person_params)
    redirect_to person
  end

  private
    def person_params
      params.require(:person).permit(:name, :age)
    end
end

以上面例子來說,新增與儲存person時,僅有姓名與年齡兩欄可以進行新增與變更其值

Rendering XML and JSON data
若是要顯示出XML或是JSON格式資料可參考以下例子

class UsersController < ApplicationController
  def index
    @users = User.all
    respond_to do |format|
      format.html
      format.xml  { render xml: @users}
      format.json { render json: @users}
    end
  end
end

接著若是執行 http://localhost:3000/users 可進到 html頁面
則執行 http://localhost:3000/users.json即可取得 json(如下圖)

螢幕快照 2017-10-27 上午12.18.21
同理,http://localhost:3000/users.xml 可取得xml資料(如下圖)

螢幕快照 2017-10-27 上午12.20.08

Filters
Filters是可以在Controller執行前,執行後,或時執行間設定要處理哪些動作
Filters可被繼承,即是ApplicationController的Filters若是已被定義了一些動做
ApplicationController底下的Controller一旦被執行就會觸發此Filters

Before Filter中的定義了可能會跳出請求,最常見的是使用者登入的判斷

class ApplicationController < ActionController::Base
  before_action :require_login

  private

  def require_login
    unless logged_in?
      flash[:error] = "You must be logged in to access this section"
      redirect_to new_login_url # halts request cycle
    end
  end
end

當ApplicationController底下的Controller執行時都會先在ApplicationController的require_login中進行判斷,因為before_action :require_login,若尚未登入則導到登入頁

若是繼承Controller但又想略過Filter,rails也提供掠過Filter的方式
譬如登入頁或是註冊帳號時不需要驗證登入,則可選擇掠過驗證是否登入,方法如下

class LoginsController < ApplicationController
  skip_before_action :require_login, only: [:new, :create]
end

 

After Filters and Around Filters
除了可以在Controller開始前執行,當然也可以在Controller動作後或是動作間執行.

after_action與before_action類似,但因為Controller動作已經執行完畢,因此無法由after_action終止Controller中的動作

而around_action可透過yield來負責執行相關動作
如以下例子,進行批審時可以輕鬆預覽

class ChangesController < ApplicationController
  around_action :wrap_in_transaction, only: :show
 
  private
 
  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      begin
        yield
      ensure
        raise ActiveRecord::Rollback
      end
    end
  end
end

發表留言