2016-11-15 3 views
0

Я новичок в рельсах, так что медведь со мной PLS. Моя проблема настолько специфична. Я создаю блог пользователя, где они могут помещать любые сообщения. Таким образом, у пользователей есть блоги, а в блогах есть сообщения. Поэтому, когда пользователь создает блог, все записи в его блоге должны быть написаны им. Другие пользователи не могут писать не в своих блогах.Настройки авторизации с использованием рельсов драгоценных камней от pundit

post_controller.rb

class PostsController < ApplicationController 
    before_action :authenticate_user! 
    before_action :authorize_user!, only: [:edit, :update, :destroy] 

    expose :blog 
    expose :post 

    def show 
    end 

    def new 
    end 

    def edit 
    end 

    def create 
    post.user = current_user 
    post.save 
    respond_with post, location: user_blog_path(post.blog.user, post.blog) 
    end 

    def update 
    post.update(post_params) 
    respond_with post, location: user_blog_path(post.blog.user, post.blog) 
    end 

    def destroy 
    post.destroy 
    respond_with post, location: user_blog_path(post.blog.user, post.blog) 
    end 

    private 

    def authorize_user! 
    authorize(post, :authorized?) 
    end 

    def post_params 
    params.require(:post).permit(:title, :content, :user_id, :blog_id) 
    end 
end 

Здесь я использую пандита разрешить пользователю, когда они обновляются или уничтожить сообщения (пользователи могут обновить или уничтожить только свои собственные сообщения), и это работает прекрасно.

просмотров/сообщений/новые

.row 
    .columns 
    h2 = title("New post") 

.row 
    .medium-5.columns 
    = simple_form_for post do |f| 
     = f.error_notification 

     .form-inputs 
     = f.input :title 
     = f.input :content 
     = f.hidden_field :blog_id, value: blog.id 
     .form-actions 
     = f.button :submit 

Здесь я использую скрытую форму, чтобы установить blog_id, который я беру из Params. Ссылка Http выглядит как http://localhost:3000/posts/new?blog_id=6. Проблема в том, что каждый пользователь может скопировать эту ссылку для создания сообщения (и они не являются владельцами блога).

post_policy.rb

class PostPolicy < ApplicationPolicy 
    def authorized? 
    record.user == user 
    end 
end 

Как я должен проверить владельца блога перед пост СОЗДАНИЯ? Возможно, у меня неправильный способ создания сообщений вроде этого (с использованием скрытой формы).

Ссылка создать новый пост

= link_to 'New Post', new_post_path(blog_id: blog.id) 
+0

Ваш 'before_action' работает только при редактировании, обновлении и уничтожении. Не уверен, что это решит проблему, но я думаю, вам нужно начать с добавления ': create' в список. – moveson

+0

@moveson, если я добавлю: create, никто не может создать сообщение. Я думаю, это потому, что в авторизованных? метод Я проверяю, если post.user = текущий пользователь? но я установил post.user после создания, поэтому в авторизованном? post.user всегда будет nill –

+0

Попробуйте положить 'authorize_user!' в следующую строку после того, как вы установите 'post.user = current_user' в свой' create' действие. – moveson

ответ

1

Я надеюсь, он будет работать для вас

application_controller.rb

class ApplicationController 

     include Pundit 

     after_action :verify_authorized, except: :index 
     after_action :verify_policy_scoped, only: :index 

     before_action :authenticate_admin_user! 

     helper_method :current_user 

     def pundit_user 
     current_admin_user 
     end 

     def current_user 
     @current_user ||= User.find(current_admin_user.id) 
     end 

    end 

posts_controller.rb

class PostsController < ApplicationController 

    before_action :set_blog 

    def new 
    authorize(Post) 
    end 

    def edit 
    @post = @blog.posts.find(params[:id]) 
    authorize(@post) 
    end 

    def index 
    @posts = policy_scope(@blog.posts) 
    end 

    private 

    def set_blog 
    @blog = current_user.blogs.find(params[:blog_id]) 
    end 

end 

post_policy.rb

class PostPolicy < ApplicationPolicy 

    def show? 
    true 
    end 

    def index? 
    true 
    end 

    def new? 
    create? 
    end 

    def create? 
    true 
    end 

    def edit? 
    update? 
    end 

    def update? 
    scope_include_object? 
    end 

    def destroy? 
    scope_include_object? 
    end 

    class Scope < Scope 

    def resolve 
     scope.joins(:blog).where(blogs: { admin_user_id: user.id }) 
    end 

    end 

    def scope_include_object? 
    scope.where(id: record.id).exists? 
    end 

end 

routes.rb

Rails.application.routes.draw do 
    devise_for :admin_users 

    resources :blogs do 
    resources :posts 
    end 
end 
+0

все еще не работает для меня –

+0

Вы используете policy_scope в своем контроллере? –

+0

нет, я не знаю, как –