2012-03-09 2 views
1

Я использую программу для аутентификации, поэтому у меня есть current_user в каждом контроллере. Мои модели:Проверить объект принадлежит current_user в контроллере (has_and_belongs_to_many)

class User < ActiveRecord::Base 
    has_many_and_belongs_to :posts 
end 

class Posts < ActiveRecord::Base 
    has_many_and_belongs_to :users 
end 

class PostsController < ApplicationController 
    before_filter :authenticate_user! 

    def show 
     @post = Post.find(params:id) 
     # need to check if @post belongs to current_user here 
     # ... 
    end 

    def edit 
     @post = Post.find(params:id) 
     # need to check if @post belongs to current_user here 
     # ... 
    end 
end 

Некоторые действия в PostsController (например показать и редактировать) нужно проверить, если сообщение извлекается из БД принадлежит CURRENT_USER. Если это не так, я хочу показать ошибку 404 и завершить выполнение (сразу после вызова ).

Очевидно, я хотел бы остаться сухим, поэтому я не хочу писать один и тот же код в каждом действии.

Я попытался написать частный метод в PostsController, однако из частного метода я не могу перенаправить на 404, а затем прервать выполнение немедленно.

A before_filter не будет работать, так как я буду исполнен перед каждым действием, и мне нужен объект @post, который выбирается внутри каждого действия.

Наконец-то я не хочу использовать дополнительные драгоценные камни, такие как CanCan.

ответ

2

Я не проверял это, но вы должны быть в состоянии сделать что-то вроде этого:

class Post < ActiveRecord::Base 
    has_many_and_belongs_to :posts 

    scope :for_user, lambda { |user| joins(:users).where("user_id = ?", user.id) 
end 

Тогда в контроллере:

Post.for_user(user).find(params[:id]) 

Таким образом, логика не повторяется, и это многоразовые ,

+0

Ммм, я думал о том, какая-то логика внутри контроллера ... но да, это довольно хорошо. Спасибо. –

0

Как насчет написания частного метода, который возвращает логическое и перенаправление в вашем основном методе на основе возвращаемого значения?

class PostsController < ApplicationController 
    before_filter :authenticate_user! 

    def show 
     redirect_to 404 if !check_my_stuff? 
     # need to check if @post belongs to current_user here 
     # ... 
    end 

    def edit 
     redirect_to 404 if !check_my_stuff? 
     # need to check if @post belongs to current_user here 
     # ... 
    end 

    private 

    def check_my_stuff? 
     @post = Post.find_by_id(params:id) 
     (@post.user == current_user) ? true : false 
    end 
end 
+1

Да, я пробовал это, однако вы повторяете перенаправление в каждом действии. –

0

код контроллера

class PostsController < ApplicationController 
    before_filter :authenticate_user! 
    before filter :load_post, :only => [:edit, :update, :show] 

    private 
    def load_post 
    @post = current_user.posts.find_by_id(params[:id) 
    @post ||= invalid_url! # defined in app controller 
    end 
end 
Смежные вопросы