2013-02-28 84 views
0

我有一个应用程序,用户可以提名一个可以查看其账户的密钥持有者。我有一个before_filter,意思是只有账户持有人或他们的钥匙持有者才能查看他们的账户。此代码适用于查看用户主页的任何人,但我无法进一步做任何事情 - 我当前以密钥持有者身份登录,并且无法注销,或者向任一帐户添加“注释”(现在钥匙持有人可以无限制地访问他们自己的账户和钥匙持有人)。请任何人都可以帮忙?rails before_filter阻止访问控制器

的是的before_filter:

def correct_user 
     @user = User.find(params[:id]) 

     unless (@user && current_user.id == @user.id) || (([email protected])&&([email protected]_id)) 
      redirect_to root_path 
     end 
     end 

,并试图例如,当我收到错误创建一个需要注意的是:

ActiveRecord::RecordNotFound in NotesController#new 
Couldn't find User without an ID 

它指的是在对的before_filter @user线。

当我作为钥匙持有人登录后,我可以查看主页,但除此之外什么也不做?谢谢!

UPDATE:

更新的before_filter(在application_controller.rb):

def correct_user 
     if params[:id] 
      @user = User.find(params[:id]) 

      unless (@user && current_user.id == @user.id) || (([email protected])&&([email protected]_id)) 
      redirect_to root_path 
      end 
     else 
      redirect_to root_path 
     end 
     end 
上说明创建

控制台输出:

Started POST "/notes" for 127.0.0.1 at 2013-02-28 14:10:49 +0000 
Processing by NotesController#create as HTML 
    Parameters: {"utf8"=>"V", "authenticity_token"=>"qMDHQAoC4l3Be5YZKSH1AJ9E5zS1D 
kMNCW2KzUZ38gM=", "note"=>{"user_id"=>"16", "content"=>""}, "commit"=>"Update Note"} 
Redirected to http://localhost:3000/ 
Filter chain halted as :correct_user rendered or redirected 
Completed 302 Found in 98ms (ActiveRecord: 0.0ms) 


Started GET "/" for 127.0.0.1 at 2013-02-28 14:10:49 +0000 
Processing by PublicController#index as HTML 
    ←[1m←[36mUser Load (3.0ms)←[0m ←[1mSELECT "users".* FROM "users" WHERE "users 
"."id" = 16 LIMIT 1←[0m 
    Rendered public/index.html.erb within layouts/application (5.0ms) 
    ←[1m←[36mTimeline Load (3.0ms)←[0m ←[1mSELECT "timelines".* FROM "timelines" 
WHERE "timelines"."user_id" = 16 LIMIT 1←[0m 
    ←[1m←[36mMessageBoard Load (2.0ms)←[0m ←[1mSELECT "message_boards".* FROM "me 
ssage_boards" WHERE "message_boards"."user_id" = 16 LIMIT 1←[0m 
    Rendered partials/_menuoptions.html.erb (53.0ms) 
Completed 200 OK in 551ms (Views: 535.0ms | ActiveRecord: 16.0ms) 
+0

当你去的音符控制器,你没有一个'PARAMS [:编号]'这是什么造成的错误。 – jvnill 2013-02-28 13:45:02

+0

为什么会出现该错误,为什么它也会阻止我注销?该id甚至没有传递给设计销毁会话操作? – ecs 2013-02-28 13:47:19

+0

你不能注销,因为之前的过滤器优先于销毁会话 – jvnill 2013-02-28 13:49:47

回答

0

试试:

def correct_user 
      if current_user 
       @user = User.find(current_user.id) 

       unless (@user && current_user.id == @user.id) || (([email protected])&&([email protected]_id)) 
       redirect_to root_path 
       end 
      else 
       redirect_to root_path 
      end 
      end 

其实这里没有params[:id]这样的东西。 current_user是您正在查看的用户,因此您可以使用上述current_user.id直接查找。用上面的代码替换,如果你找到其他的可能性最好。这只是一个实施的想法。

+0

我仍然怀疑帐户所有者或密钥持有者是您在'correct_user'操作中传递的id的人。只要找出你为什么没有得到那个人的身份证。你不能把这个'before_filter'直接放在应用程序控制器中,因为它会直接传递这个人的nil参数。一开始你没有任何这样的人来检查。您必须在应该传递给'correct_user'动作的地方提供person id参数。 – 2013-02-28 14:42:55

+0

我的错误 - 我在我的控制器中有一个流氓代码片段,我曾尝试在动作中传递该ID。删除,并过滤器正常工作,感谢您的帮助! – ecs 2013-02-28 14:46:55

0

我认为你验证上太多无论如何,这个问题似乎在get/post请求中,因为没有id到达控制器动作,你能附加发送给控制器的参数吗?从控制台复制它们,这将是更容易阅读...

"note"=>{"user_id"=>"16", "content"=>""} 

您对使用params[:note][:user_id]来获取用户ID,你必须与用户ID添加一个隐藏字段能做你想做的事情,如果你问我,我不认为这是一种好的做法,你有没有看过任何Railscast?,我敢肯定,你可以在那里找到很多有用的技巧,看看这个例如:

Railscast Cancan

希望它可以帮助...

+0

我已经将它添加到原来的问题 – ecs 2013-02-28 14:16:25

+0

是的,我已经看到了CanCan上的一个,并且在尝试自己做这件事之前查看了文档 - 它似乎并不是只允许一个用户访问另一个用户指定的帐户,只是不同级别的用户,即管理员,用户等,谁拥有所有帐户相同的权限? – ecs 2013-02-28 14:30:45

+0

随着康康舞,你可以定义你想要的所有权限,它在某些情况下,一个有点棘手,但这里的容易的道路,我相信这是形式保存用户ID的上一个隐藏字段.. – kainlite 2013-02-28 14:35:10

0

当你去注释/新的时候,你没有提供任何id参数,这就是你得到这个异常的原因。

你必须先检查是否PARAMS [:ID]存在:

def correct_user 
    if params[:id] 
    @user = User.find(params[:id]) 

    unless (@user && current_user.id == @user.id) || (([email protected])&&([email protected]_id)) 
     redirect_to root_path 
    end 
    else 
    redirect_to root_path 
    end 
end 

,并在链接到Notes /新,你必须提供用户ID PARAM:

<%= link_to "New note on #{@user.name}", new_note_path(id: @user.id) %> 
+0

只是好奇,关于上面的'link_to' :为什么需要在新行动中使用参数ID? 'new.html.erb'的形式将自动创建子上的id,因为这是主键自动增量字段。 – 2013-02-28 13:53:40

+0

但是这种情况下的ID不是在笔记模型中查找的,而是用于用户模型 – Alejo 2013-02-28 13:55:21

+0

即使id不查找,如果我们做了如下操作:'Notes.create(:field1 =>“value1 “,:field2 =>”value2“)'不给id值,那么它也会创建自动id增加的行。此外,创建操作需要的是id,而不是新的操作,因为它是我们发送id params的地方。 – 2013-02-28 13:58:39