Home > Software engineering >  How to immediatly set a variable in a controller?
How to immediatly set a variable in a controller?

Time:02-24

Briefly, here's my associations:

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

I've a view where 2 forms are displayed:

  1. one for adding a new Calendar, associated to a Team
  2. one for adding a new Event, associated to a Calendar

In my controller, I set up variables with something like:

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

But in my view, @calendar is called before @calendars

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

Thus in the events/form partial, the <select> tag contains a line for each calendar, plus one for the newly built calendar (which is empty, baah, ugly).


QUESTION: How could I set (eager load ?) the @calendars so it does not contains non-prersisted records ?


A simple solution that does not immediately set the @calendars variable, but at least does not pollute it:

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

CodePudding user response:

You can call load to immediately load the records from the database.

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

CodePudding user response:

Another way to do this is to use eager_load and to simply avoid building the record off the collection:

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

Or you can use dup to avoid mutating the original object:

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