我正在使用设计进行身份验证,所以我在每个控制器中都有一个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这样的其他宝石。
答案 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