Prevent controller action from direct execution by user in Rails
I have a situation where i need to prevent users from explicitly calling say /town/addBuilding. Town is my controller and addBuilding is the action that is executed.
Now, the thing is that this action should only be executed in my program's code and not by a user requesting to execute it. Moreover, this action is executed like a callback. In my application_controller, when some condition is met, the controller action is triggered and there is a redirection. In php, a simple guard like defining a guard and checking against it would be enough. Is there an equivalent thing in rails and if so, what is the best way to implement it ?
Thanx for reading and i appreciate your help :)
EDIT: I'm pasting some code to make it clearer, note that /town/addBuilding was an example, the controller names and actions below are differently named.
Now, that is the actual application controller code, it is part of a browser game that i'm coding.
def checkQuest
if TavernQuest.hasQuest(current_user)
quest = TavernQuest.getQuest(current_user)
if quest.end_time < Time.now # get quest info and check if the quest has been completed
TavernQuest.deleteQuest(current_user)
redirect_to :controller =>开发者_运维百科; 'tavern', :action => 'monsterAttack'
end
end
end
The tavern controller action is just the plain code that i want to execute, but only if the redirection happens inside the application controller.
It seems that you are trying to put logic into a controller which actually should belong in a model or a library.
Why do i say this: aside from the current_user and the redirect, all the code is more related to your model (where the knowledge should be) and not your controller. Your model knows when a user's quest is expired.
Example implementation:
class TavernQuest
def self.user_quest_is_expired?(user)
quest = getQuest(current_user)
if quest && quest.end_time < Time.now
TavernQuest.deleteQuest(current_user)
true
else
false
end
end
end
and in your controller you just need to write
redirect_to :controller => 'tavern', :action => 'monsterAttack' if TavernQuest.user_quest_is_expired?(current_user)
Put the addBuilding method under a line that starts with protected, as follows
protected
def addBuilding
#your code
end
Enjoy!
EDIT: In addition to this you might also wanna use the before_filter in your controllers... I'll post the exact syntax soon.
before_filter :addBuilding, :only => :method_name
method_name is the method from which :addBuilding can be accessed, no other method can access this method after adding in this line..
EDIT: Ok, so based on the info you provided, protected
wont work since if we put your secret action under protected
only the tavern
controller will have access to it.
EDIT: Please consider using Sessions to check if the users have a valid session when they try to to execute the monsterAttack
action..
精彩评论