一个控制器,普通用户和管理员的不同视图
在我的应用程序中,我有一个“用户”模型。每个用户可以有多个(电子邮件)地址,这些地址在模型“Address”中定义:
Class User < ActiveRecord::Base
has_many :addresses
def is_authorized(op)
# returns true or false
end
def is_owned_by(user)
# returns true or false
end
end
Class Address < ActiveRecord::Base
belongs_to :user
end
在 AddressController 类中,当前登录的用户在“@user”实例变量中可用。控制器阻止普通用户编辑、删除、查看等不属于他们的地址 - 但他确实允许管理用户编辑这些地址。 AddressController 类可以询问 AddressModel 当前登录的用户是否正在执行正常操作或超级用户操作。
这一切都运行良好,并且数据库更新按预期进行,但是,我真的希望根据操作模式有不同的 HTML 视图。我只能想到两种方法来实现这一点:
- 在AddressController类中了解操作模式(正常/特权)(使用实例变量,例如@privileged)并在视图中使用“if”语句。
- 在地址控制器中使用类似“after_filter”的东西来渲染不同的布局。
如果可以根据操作模式以两种完全不同的布局显示执行单个控制器的结果,那么实现这一目标的好方法是什么?
提前致谢 斯特凡
in my application, I have a "User" model. Each user can have multiple (email) addresses which are defined in the model "Address":
Class User < ActiveRecord::Base
has_many :addresses
def is_authorized(op)
# returns true or false
end
def is_owned_by(user)
# returns true or false
end
end
Class Address < ActiveRecord::Base
belongs_to :user
end
Inside the AddressController class, the currently logged in user is available in the "@user" instance variable. The controller prevents ordinary users from editing, deleting, viewing etc. addresses which don't belong to them - but he does allow an administrative user to edit those. The AddressController class can ask the AddressModel if the user currently logged in is performing normal or superuser operations.
This all works nicely and database updates are made as expected, however, I'd really like to have different HTML views depending on the mode of operation. I can only think of two ways to achieve that:
- Make the mode of operation (normal/privileged) known in the AddressController class (using an instance variable, e.g. @privileged) and use an "if" statement in the view.
- Use something like an "after_filter" in the address controller to render a different layout.
If it is possible to display the results of executing a single controller in two completely different layouts, depending on it's mode of operation, what is a good way to achieve that?
Thanks in advance
Stefan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以在操作本身中指定使用哪个视图来显示操作的结果。您还可以指定要使用的布局。因此,例如:
这将根据
is_authorized
返回的值呈现admin_action.html.erb
或non_admin_action.html.erb
。:layout
选项是,呃,可选的,引用视图/布局中的布局。您可以在渲染文档。You can specify which view to use to display the result of an action in the action itself. You can also specify which layout to use too. So, for example:
This will render either
admin_action.html.erb
ornon_admin_action.html.erb
depending on the returned value fromis_authorised
. The:layout
option is, er, optional and refers a layout in views/layouts. There are various other options the render call which you can find in the documentation for render.您可以通过以下方式指定该特定控制器或应用程序控制器中的整个应用程序的视图布局:
您可以尝试在此处弄清楚:http://guides.rubyonrails.org/layouts_and_rendering.html#using-render,位于 2.2.12 查找布局下
希望这有帮助 = )
You can specify the layout of the view for that particular controller, or the whole application in the application controller by:
You can try to figure it out here: http://guides.rubyonrails.org/layouts_and_rendering.html#using-render, under 2.2.12 Finding Layouts
Hope this helps =)
您只需在控制器末尾手动调用 render 方法即可操作:
这将渲染
app/views/myview/show_privileged.html.erb
或app/views/myview/show.html.erb
。或者,您可以使用:template
选项为 render 方法提供显式模板文件。You can simply call the render method manually at the end of your controller action:
This will render
app/views/myview/show_privileged.html.erb
orapp/views/myview/show.html.erb
. Alternatively, you can use the:template
option to give an explicit template file to the render method.如果这是您的应用程序中唯一一个您可以在各处使用 if/else 的控制器,那可能没问题。如果你开始到处做这种类型的逻辑,那应该告诉你你一次做的太多了。
您接受的答案(很好并且有效!)具有不同的布局和不同的视图,对我来说,这表明控制器做得太多 - 我会将其拆分为管理控制器。
If this is the only controller in your app where you're if/else'ing all over the place that's probably fine. If you start doing this type of logic everywhere that should tell you that you're doing too much at once.
The answer you accepted (which is fine and works!) has a different layout and a different view, to me that says the controller is doing too much - I'd split this out into an admin controller.
您应该将管理操作放在管理命名空间中并在那里进行限制。在你的控制器目录中创建一个名为
admin
的目录,并在其中添加一个 _application_controller.rb_ :现在你可以将控制器放入这个命名空间中,并让它们也继承自
Admin::ApplicationController
。You should put administrative actions in an an administrative namespace and restrict it there. Create a directory called
admin
in your controllers directory and add an _application_controller.rb_ in there:Now you can put controllers into this namespace and make them inherit from
Admin::ApplicationController
too.