如何立即在控制器中设置变量?

How to immediatly set a variable in a controller?

简单地说,这是我的联想:

Team:     has_many   :calendars
Calendar: has_many   :events
          belongs_to :team
Event:    belongs_to :calendar

我有一个显示 2 个表单的视图:

  1. 一个用于添加与团队关联的新日历
  2. 一个用于添加与日历关联的新事件

在我的控制器中,我设置了如下变量:

@team      = Team.find(params[:id])
@calendars = @team.calendars
@calendar  = @team.calendars.build

但在我看来,@calendar在之前被称为@calendars

<%= render partial: 'calendars/form', locals: { calendar:  @calendar,  ... } %>
<%= render partial: 'events/form',    locals: { calendars: @calendars, ... } %>

因此在 events/form 部分中,<select> 标签包含一行用于每个日历,另外还有一行用于新建日历(这是空的,糟糕,丑陋)。


问题:我如何设置(预先加载?)@calendars 使其不包含非保留记录?


一个简单的解决方案,不会立即设置@calendars变量,但至少不会污染它:

@calendar = Calendar.new(team_id: @team.id)

您可以调用load立即从数据库中加载记录。

@team      = Team.find(params[:id])
@calendars = @team.calendars.load
@calendar  = @team.calendars.build

另一种方法是使用 eager_load 并简单地避免从集合中构建记录:

@team      = Team.eager_load(:calendars)
                 .find(params[:id])
@calendars = @team.calendars
@calendar  = Calender.new(team: @team)

或者您可以使用 dup 来避免改变原始对象:

@team      = Team.eager_load(:calendars)
                 .find(params[:id])
@calendars = @team.calendars
@calendar  = @team.calendars.dup.new(team: @team)