如何将多个活动记录对象从控制器传递到视图?

时间:2013-12-04 08:28:53

标签: ruby-on-rails

新手问题

我正在构建员工表单,表单中的一个字段是数据来自部门的选项列表。

ActiveRecords:员工和部门。

我要将员工和部门的活动记录从控制器传递到视图。如何将这些多个活动记录传递给视图以创建使用部门构建选择列表的员工?

2 个答案:

答案 0 :(得分:4)

常见的Rails方法只是在控制器操作中设置实例变量:

方法1:

class EmployeesController < ApplicationController

  def new
    @departments = Department.all
    @employee    = Employee.new
  end

end

在你的意见中:

<%= form_for(@employee) do |f| %>

  ...

<% end %>

Rails在幕后做了一些魔术,将控制器的实例变量暴露给视图模板。

许多人(包括我自己)认为允许视图模板对象访问 控制器的实例变量直接违反了面向对象的编程。对象的实例变量只能由该实例访问。

方法2:

更好的方法是将这些变量包装在getter方法中,然后将其定义为辅助方法:

class EmployeesController < ApplicationController

  # Make these methods available to the view.
  helper_method :departments, :employee

  def new
  end


  # Private - as they're not actions
  private

  def departments
    @departments = Department.all
  end

  def employee
    @employee = Employee.new
  end

end

在你的意见中:

<!-- NOTE - no @ sign, it's not an instance variable -->
<%= form_for(employee) do |f| %>

  ...

<% end %>

在这种情况下,您将为EmployeeController定义一个公共API,其中包含两个可以访问的方法,部门和员工。

实际上,这是第一个作为第一个例子;差异主要是学术上的。

方法3:

对于需要访问控制器中定义的几个不同变量的复杂视图,您可以设计自己的演示者(或 facade )对象。

这可能对您的员工表单有些过分,但以此为例:

class EmployeesController < ApplicationController

  # Make these methods available to the view.
  helper_method :employee_form_presenter

  def new
  end


  # Private - as they're not actions
  private

  def employee_form_presenter
    @employee_form_presenter = EmployeeFormPresenter.new(params) # you can pass args from the controller if you need them
  end

end

创建演示者:

# in app/presenters/employee_form_presenter.rb
class EmployeeFormPresenter

  attr_reader :employee, :departments

  def initialize(eployee_atts={})
    @employee = Employee.new(eployee_atts)
    @departments = Department.all
  end

end

在你看来:

<%= form_for(employee_form_presenter.employee) do |f| %>

  ...
  <% for dept in employee_form_presenter.departments do %>

    ...

  <% end %>

<% end %>

这使您的控制器真正干净简单 - 使测试更容易,并为其添加额外的行为。

所有这些方法都有效。只有当控制器开始变得更复杂时才需要演示者。但就个人而言,我 避免从视图中调用控制器的实例变量作为最佳实践。

答案 1 :(得分:0)

假设您的视图名称为 employee_form.html.erb ,然后在您的控制器中应该有一个具有相同名称的方法(不是必需的)。

def employee_form
  @employee = Employee.first
  @department = Department.first
end

然后您可以在 employee_form.html.erb 视图中访问这些实例变量,例如

<%= @employee.name %>
<%= @department.name %>