Check对象属于Controller中的current_user(has_and_belongs_to_many)

时间:2012-03-09 19:29:15

标签: ruby-on-rails

我正在使用设计进行身份验证,所以我在每个控制器中都有一个current_user。我的模特是:

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 中的一些操作(例如 show edit )需要检查从数据库获取的帖子是否属于当前用户。如果没有,我想显示404错误并结束执行(就在查找调用之后)。

显然我想保持DRY,所以我不想在每个动作中都写相同的代码。

我尝试在 PostsController 中编写私有方法,但是从私有方法我无法重定向到404然后立即中断执行。

由于我会在每个操作之前执行,因此before_filter将无法工作,我需要在每个操作中获取的 @post 对象。

最后,我不想使用像CanCan这样的其他宝石。

3 个答案:

答案 0 :(得分: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])

这样逻辑就不会重复,而且可以重复使用。

答案 1 :(得分:0)

如何根据返回值编写一个返回布尔值并在main方法中重定向的私有方法?

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

答案 2 :(得分: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