I’m using a nested form to enter worked time weekly. So when creating a new week entry of 7 days I create a form as follows:
#timesheets/new.html.erb
<%= form_for @timesheet do |f| %>
<%= render ‘fields’, f: f %>
<%= f.submit class: ‘btn btn-large btn-primary’%>
<% end %>
#timesheets/_fields.html.erb
…
<% @timesheet.date_range(@timesheet.start_date, @timesheet.end_date).each do |week_date| %>
<th><%= week_date.to_formatted_s(:short) %></th>
<% end %>
<%= f.fields_for :activities do |builder|%>
<%= render "activity_fields", :f => builder %>
<% end %>
…
#timesheets/_activity_fields.html.erb
<td><%= f.collection_select(:task_id, @tasks, :id, :name, :prompt => true) %></td>
<%= f.fields_for :time_entries do |builder|%>
<%= render 'time_entries_fields', :f => builder %>
<% end %>
…
#timesheets/_activity_fields.html.erb
<%= f.hidden_field :workdate %>
<%= f.text_field :worktime, size: 3 %>
No problem for create a week entry and to display it in the show.html.erb page:
#timesheets.show.html.erb
<% provide(:title, ‘Timesheet details’)%>
<strong>Start Date:</strong>
<%= @timesheet.start_date.to_formatted_s(:rfc822) %>
<strong>End Date:</strong>
<%= @timesheet.end_date.to_formatted_s(:rfc822) %>
<strong>Status:</strong>
<%= @timesheet.status %>
<% if @activities.empty? %>
No activities found
<% else %>
activities list
<% @timesheet.date_range(@timesheet.start_date, @timesheet.end_date).each do |week_day| %>
<th><%= week_day.to_formatted_s(:short)%></th>
<%end%>
<% @activities.each do |activity| %>
<tr>
<td><%= activity.task.name %></td>
<% @timesheet.date_range(@timesheet.start_date, @timesheet.end_date).each do |week_day| %>
<td><%= activity.daily_spent(week_day) %></td>
<% end %>
</tr>
<% end %>
Activity |
---|
<%= will_paginate @activities %>
<% end %>
<%= link_to ‘Back’, timesheets_path %> | <%= link_to ‘Edit’, edit_timesheet_path(@timesheet) %>
The problem is in the edit page: the existing day entries do not match with the table column header displaying week day. I mean that the existing worked time values are displayed first, and the empty text fields just follow them:
So here is what was entered when creating a new week entry:
Task | 11-03 | 12-03 | 13-03 | 14-03 | 15-03 | 16-03 | 17-03 |
Task-1 | 0.5 | 1 | |
Task-2 | 0.5 | | 1 |
So instead of displaying the table fields in the same way as it was during the creation, the edit page is displayed as follows:
Task | 11-03 | 12-03 | 13-03 | 14-03 | 15-03 | 16-03 | 17-03 |
Task-1 | 0.5 | 1 | |
Task-2 | 0.5 | 1 | |
Here is how it is defined in the controller:
#timesheets_controller.rb
…
def show
@timesheet = current_user.timesheets.find(params[:id])
@activities = @timesheet.activities.paginate(page: params[:page])
end
def new
@timesheet = current_user.timesheets.new
activity = @timesheet.activities.build
@timesheet.create_activity_days(activity)
end
def create
@timesheet = current_user.timesheets.new(params[:timesheet])
@timesheet.status = Timesheet::SUBMITTED
if @timesheet.save
flash[:success] = ‘Timesheet created sucessfully’
redirect_to @timesheet
else
render ‘new’
end
end
def edit
@timesheet = current_user.timesheets.find(params[:id])
@timesheet.activities.each do |activity|
@timesheet.date_range(@timesheet.start_date, @timesheet.end_date).each do |week_day|
unless activity.worked_days.include?(week_day)
activity.time_entries.build(workdate: week_day)
end
end
end
end
…
Of course, the models have their definition as follows:
#timesheet.rb
class Timesheet < ActiveRecord::Base
attr_accessible :status, :user_id, :start_date, :end_date, :activities_attributes
has_many :activities, dependent: :destroy
has_many :time_entries, through: :activities
accepts_nested_attributes_for :activities, :allow_destroy => true, :reject_if => proc { |attributes| attributes[‘task_id’].blank? }
…
end
#activity.rb
class Activity < ActiveRecord::Base
attr_accessible :task_id, :timesheet_id, :time_entries_attributes
has_many :time_entries, order: :workdate, dependent: :destroy
accepts_nested_attributes_for :time_entries, :allow_destroy => true, :reject_if => proc { |attributes| attributes[‘worktime’].blank? }
…
end
#time_entry.rb
class TimeEntry < ActiveRecord::Base
attr_accessible :activity_id, :workdate, :worktime
belongs_to :activity
…
end
Any idea how to solve that? Thank you.