所以我把fat model skinny controller铭记于心。
我已经使用验证从控制器向模型移动了很多检查(即创建新对象)。有没有办法利用我现在强大的控制器验证套件来确定我的视图中应显示的内容?我在想:
# in the controller
@item = Item.new if valid?
# then in the view:
<% if @item %><%= #button to create new item %>...
另一个用例:
<% if @comment.valid? %><div class="new comment"></div><% end %>
我将需要为某些字段传递“虚拟”值以使验证通过,但是我最关心的是“是否允许用户这样做”类型的东西< / strong>即可。对于哲学问题感到抱歉,但这里的最佳做法是什么?
以下是我拥有的权限验证示例。我想保持DRY并使用它而不是复制并尽可能将其粘贴到控制器。
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :commentable, :polymorphic => true
validate :user_can_comment, :if => :user
def user_can_comment
errors.add(:user, "can't comment") unless (user.is_photographer || user.id == commentable.user_id)
end
end
答案 0 :(得分:1)
似乎你想要的是Presenter Pattern。这将帮助您将复杂的视图逻辑清理为演示者对象。
还有一个非常漂亮的宝石可以帮助你利用这种模式:Draper。不要忘记查看关于主题的railscast:http://railscasts.com/episodes/286-draper
答案 1 :(得分:1)
看起来你在这里混淆了一些问题。验证不应用于访问控制。有效用户可能可以访问或不访问应用程序的某些部分,因此永远不应该首先创建无效用户。无效用户确实存在,但仅在呈现带有错误消息的表单期间。他们永远不会得救。
rails中最基本的脚手架控制器会向您显示控制器的外观。
# Example of registration form
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to root_url, notice: 'Welcome!'
else
render :new
end
end
end
在上面的代码中注意render :new
行。当@user
无法保存时会发生这种情况。为什么不能呢?因为验证失败了。你怎么知道哪些验证失败了?通过查看为您填充的@user.errors
。这就是我们渲染而不是重定向的原因。重定向后,@user.errors
数组将不再存在。因此,在您看来,您只需走过@user.errors.full_messages
并很好地展示它们。
权限是一个完全不同的故事。如果您的用户可以是管理员,那么您的用户表上可能有一个名为admin的布尔列。这将自动为您提供@user.admin?
方法。在您的控制器和视图中,您将基于会话current_user
,因此您可以使用current_user.admin?
。很多人在他们的ApplicationController中执行以下操作。
class ApplicationController < ActionController::Base
# ...
helper_method :admin?
def admin?
current_user.present? && current_user.admin?
end
end
这将为您的所有控制器和视图提供一个名为admin?
的方法,您可以使用该方法确定用户是否可以访问某些内容。更复杂的权限需要使用角色。 Ryan Bates有一个名为CanCan的漂亮图书馆,可以提供帮助。