Turning a calendar into a form using Rails?

2019-05-26 21:49发布

问题:

Question: How do I turn a calendar into a form where the dateselect is rendered to match the calendar day instead of the current date?


What I'm trying to do: I'd like to create a calendar that displays the cyclist's workouts.

  • Create workouts within each calendar day, automatically rendering the workoutdate that matches the given day in the form

Each workout has many intervals. Each calendar day has one workout.

Plugins: Extracted the table_builder.rb and calendar_helper.rb from https://github.com/p8/table_builder (both gem and plugin do not deploy with rails 3.1)

class WorkoutsController.rb

  def new
    @workout = Workout.new
    @date = params[:month] ? Date.parse(params[:month].gsub('-', '/')) : Date.today
    3.times do
      @workout.intervals.build
    end
  end

Workout.rb

  attr_accessible :workoutdate, :intervals_attributes
  has_many :intervals, :dependent => :destroy
  accepts_nested_attributes_for :intervals, :reject_if => lambda { |a| a[:interval_name].blank? }, :allow_destroy => true

Interval.rb

attr_accessible :interval_name, :workout_id
belongs_to :workout

views/workouts/new.html.erb

<div id ="calendar">
  <%= calendar_for @workouts, :year => @date.year, :month => @date.month do |calendar| %>
    <%= calendar.head('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') %>
    <% calendar.day(:day_method => :workoutdate) do |date, workouts| %>
      <%= date.day %>
      <%= render 'form' %>
    <% end %>
  <% end %>
</div>

views/workouts/_form.html.erb

<%= nested_form_for @workout do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :workoutdate %><br />
    <%= f.date_select :workoutdate %>
  </p>
  <%= f.fields_for :intervals %>
  <p><%= f.link_to_add "Add interval", :intervals %></p>
  <p><%= f.submit "Submit" %></p>
<% end %>

views/workouts/_interval_fields.html.erb

<p>
  <%= f.label :interval_name, "Interval" %>
  <%= f.text_field :interval_name %>
  <%= f.link_to_remove "remove" %>
</p>

currently up on heroku http://billeee.herokuapp.com/workouts

回答1:

Since you have the date available in the block of the day method, you should be able to pass it on to the partial like so:

<% calendar.day(:day_method => :workoutdate) do |date, workouts| %>
  <%= date.day %>
  <%= render 'form', :date => date %>
<% end %>

Then you can make use of it within the form partial and set the date of the date select via the local variable you have just passed in:

<%= f.date_select :workoutdate, :default => date %>

As a note: this method seems a bit funny, since you're rendering this form always for a particular day anyways. Why not send the date e.g. via a hidden input field? Is the user supposed to change the date? And if so, doesn't that break the UI logic?