<<前 [TOP] 次>>
Railsのフィルタ機能を使い商品登録ページへのアクセス制限を実装していきます。
まずは「app/controllers」フォルダにある「application_controller.rb」ファイルの編集です。
【app/controllers/application_controller.rb】
class ApplicationController < ActionController::Base before_filter :authorize # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception private def current_cart Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound cart = Cart.create session[:cart_id] = cart.id cart end protected def authorize unless User.find_by_id(session[:user_id]) redirect_to login_url, notice: "ログインして下さい。" end end end
まず最初に「before_filter :authorize
」として、アプリケーションのすべてのアクションの前にauthorize()が呼び出されるようにしています。
「authorize()」の記述は一番最後とし、「protected」にしています。
protected def authorize unless User.find_by_id(session[:user_id]) redirect_to login_url, notice: "ログインして下さい。" end end
このままだとすべてのページにアクセス制限がかかってしまうので、「market」「sessions」「carts」「line_items」「orders」の各コントローラに「skip_before_filter」という除外の呼び出しを追加します。
【app/controllers/market_controller.rb】
class MarketController < ApplicationController skip_before_filter :authorize def index @goods = Good.select_shop respond_to do |format| format.html format.json { render :xml => @good } end end end
【app/controllers/sessions_controller.rb】
class SessionsController < ApplicationController skip_before_filter :authorize def new end def create user = User.find_by_name(params[:name]) if user and user.authenticate(params[:password]) session[:user_id] = user.id redirect_to admin_url else redirect_to login_url, alert: '無効なユーザ/パスワードの組み合わせです。' end end def destroy session[:user_id] = nil redirect_to login_url, alert: "ログアウトしました。" end end
【app/controllers/carts_controller.rb】
class CartsController < ApplicationController before_action :set_cart, only: [:show, :edit, :update, :destroy] before_action :set_cart, only: [:show, :edit, :update, :destroy] # GET /carts # GET /carts.json def index @carts = Cart.all end # GET /carts/1 # GET /carts/1.json def show begin @cart = Cart.find(params[:id]) rescue ActiveRecord::RecordNotFound logger.error "無効なカート#{params[:id]}にアクセスしようとしました。" redirect_to market_url, notice: '無効なアクセスです。' else respond_to do |format| format.html format.json { render json: @cart } end end end # GET /carts/new def new @cart = Cart.new end # GET /carts/1/edit def edit end # POST /carts # POST /carts.json def create @cart = Cart.new(cart_params) respond_to do |format| if @cart.save format.html { redirect_to @cart, notice: 'Cart was successfully created.' } format.json { render :show, status: :created, location: @cart } else format.html { render :new } format.json { render json: @cart.errors, status: :unprocessable_entity } end end end # PATCH/PUT /carts/1 # PATCH/PUT /carts/1.json def update respond_to do |format| if @cart.update(cart_params) format.html { redirect_to @cart, notice: 'Cart was successfully updated.' } format.json { render :show, status: :ok, location: @cart } else format.html { render :edit } format.json { render json: @cart.errors, status: :unprocessable_entity } end end end # DELETE /carts/1 # DELETE /carts/1.json def destroy @cart = current_cart @cart.destroy session[:cart_id] = nil respond_to do |format| format.html { redirect_to market_url, notice: 'カートが空になりました。' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_cart @cart = Cart.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def cart_params params.fetch(:cart, {}) end end
「skip_before_filter :authorize」の対象を「:show」「:create」「:update」「:destroy」に限定しています。
【app/controllers/line_items_controller.rb】
class LineItemsController < ApplicationController skip_before_filter :authorize, only: [:create, :destroy] before_action :set_line_item, only: [:show, :edit, :update, :destroy] # GET /line_items # GET /line_items.json def index @line_items = LineItem.all end # GET /line_items/1 # GET /line_items/1.json def show end # GET /line_items/new def new @line_item = LineItem.new end # GET /line_items/1/edit def edit end # POST /line_items # POST /line_items.json def create @cart = current_cart good = Good.find(params[:good_id]) @line_item = @cart.add_good(good.id) respond_to do |format| if @line_item.save format.html { redirect_to @line_item.cart, notice: 'カートに商品が追加されました。' } format.json { render :show, status: :created, location: @line_item } else format.html { render :new } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end # PATCH/PUT /line_items/1 # PATCH/PUT /line_items/1.json def update respond_to do |format| if @line_item.update(line_item_params) format.html { redirect_to @line_item, notice: 'Line item was successfully updated.' } format.json { render :show, status: :ok, location: @line_item } else format.html { render :edit } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end # DELETE /line_items/1 # DELETE /line_items/1.json def destroy @line_item.destroy respond_to do |format| format.html { redirect_to cart_url(@line_item.cart_id), notice: '商品をカートから削除しました。' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_line_item @line_item = LineItem.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def line_item_params params.require(:line_item).permit(:good_id, :cart_id) end end
「skip_before_filter :authorize」の対象を「:create」「:destroy」に限定しています。
【app/controllers/orders_controller.rb】
class OrdersController < ApplicationController skip_before_filter :authorize, only: [:new, :create] before_action :set_order, only: [:show, :edit, :update, :destroy] # GET /orders # GET /orders.json def index @orders = Order.paginate :page=>params[:page], :per_page =>10 respond_to do |format| format.html format.json { render json: @orders } end end # GET /orders/1 # GET /orders/1.json def show end # GET /orders/new def new @cart = current_cart if @cart.line_items.empty? redirect_to market_url, notice: 'カートは空です。' return end @order = Order.new respond_to do |format| format.html format.json { render json: @order } end end # GET /orders/1/edit def edit end # POST /orders # POST /orders.json def create @order = Order.new(order_params) @order.add_items(current_cart) respond_to do |format| if @order.save Cart.destroy(session[:cart_id]) session[:cart_id] = nil format.html { redirect_to market_url, notice: 'ご注文ありがとうございました。' } format.json { render json: @order, status: :created, location: @order } else format.html { render :new } format.json { render json: @order.errors, status: :unprocessable_entity } end end end # PATCH/PUT /orders/1 # PATCH/PUT /orders/1.json def update respond_to do |format| if @order.update(order_params) format.html { redirect_to @order, notice: '注文情報を更新しました。' } format.json { render :show, status: :ok, location: @order } else format.html { render :edit } format.json { render json: @order.errors, status: :unprocessable_entity } end end end # DELETE /orders/1 # DELETE /orders/1.json def destroy @order.destroy respond_to do |format| format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_order @order = Order.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def order_params params.require(:order).permit(:name, :address, :email, :tel_number, :pay_type) end end
「skip_before_filter :authorize」の対象を「:new」「:create」に限定しています。
管理ビューに各リンクを追加します。
【app/views/admin/index.html.erb】
<h1>管理者</h1> <br> <%= button_to 'ログアウト', logout_path, method: :delete %> <br> <h2>ログインしています。</h2> <p>現在時刻:<%= Time.new %></p> <br> <%= link_to '注文を見る', orders_path, class: 'btn' %><span> </span><%= link_to '商品登録',goods_path, class: 'btn' %><span> </span><%= link_to 'ユーザ管理', users_path, class: 'btn' %>
では「http://localhost:3000/goods」にアクセスしてみます。
このようにログインページが表示されました。
ログインします。
各ページへアクセス出来ます。
ではログアウトします。
「http://localhost:3000/goods」にアクセス出来なくなりました。
↓↓クリックして頂けると励みになります。