创建多次向表添加条目

时间:2015-02-14 23:08:59

标签: ruby-on-rails model-view-controller

我有一个包含多个datetime字段的模型,所有字段都具有相同的日期,但时间不同。因此,在我对该模型的表格中,我要求提供一次日期,然后要求其他每个人的时间,以避免一遍又一遍地要求同一日期。

一旦我的表单将params哈希值返回给我的控制器,我就有一个函数add_date_to_time,它遍历每个键并将其日期值设置为表单中前面输入的日期。然后它应该从哈希中删除日期键,并且不会 - 任何输入,只要为什么发生这种情况将被赞赏。

我遇到两个大问题:

1)最重要的一个 - 它创造了7次入口。因此,如果我添加一个节目,该节目将被添加到数据库7次而不是一次。此外,当我回到节目索引时,我在表单上点击提交后,表示没有收到任何数据。如果我重新加载它,页面就会正确显示。

2)较小的问题 - 允许散列中所有不同键的代码是可怕的。是否有更好的方法可以同时允许多个密钥?

我的课程:

Show的模型

class Show < ActiveRecord::Base
  attr_accessor :date
end

Show

的控制器
class ShowsController < ApplicationController
  helper ShowsHelper

  def index
    @shows = Show.all
  end

  def new
    @show = Show.new
  end

  def create
    add_date_to_times
    if Show.create permit_params
      redirect_to 'shows', alert: 'Show successfully created'
    else
      redirect_to 'shows'
    end
  end

  private
  def permit_params
    params.require(:show).permit(:artist, :'date(1i)', :'date(2i)', :'date(3i)', :'doors_open(1i)', :'doors_open(2i)', :'doors_open(3i)',
                                 'doors_open(4i)', :'doors_open(5i)', :'dinner_starts(1i)', :'dinner_starts(2i)',
        'dinner_starts(3i)', :'dinner_starts(4i)', :'dinner_starts(5i)', :'dinner_ends(1i)', :'dinner_ends(2i)',
                                 'dinner_ends(3i)', :'dinner_ends(4i)', :'dinner_ends(5i)', :'show_starts(1i)', :'show_starts(2i)',
                                 'show_starts(3i)', :'show_starts(4i)', :'show_starts(5i)', :'show_ends(1i)', :'show_ends(2i)',
                                 'show_ends(3i)', :'show_ends(4i)', :'show_ends(5i)')
  end

  private
  def add_date_to_times
    append_date_to_time 'doors_open'
    append_date_to_time 'dinner_starts'
    append_date_to_time 'dinner_ends'
    append_date_to_time 'show_starts'
    append_date_to_time 'show_ends'
    params.delete 'date(3i)'
    params.delete 'date(2i)'
    params.delete 'date(1i)'
    #%w(1 2 3).map { |e| params.delete("date(#{e}i)")}
  end

  def append_date_to_time(attribute)
    %w(1 2 3).map { |e| params[:show]["#{attribute}(#{e}i)"] = params[:show]["date(#{e}i)"] }
  end
end

Show

的新表单
=form_for @show, html: {role: "form"} do |f|
  .form-group
    =f.label :artist
    =f.text_field :artist, class: "form-control"
  .form-group
    =f.label :date
    =f.date_select :date, order: [:day, :month, :year], class: "form-control"
  .form-group
    =f.label :doors_open
    =f.time_select :doors_open, class: "form-control"
  .form-group
    =f.label :dinner_starts
    =f.time_select :dinner_starts, class: "form-control"
  .form-group
    =f.label :dinner_ends
    =f.time_select :dinner_ends, class: "form-control"
  .form-group
    =f.label :show_starts
    =f.time_select :show_starts, class: "form-control"
  .form-group
    =f.label :show_ends
    =f.time_select :show_ends, class: "form-control"
  .form-group
    =f.submit "Create Show", class: "btn btn-default"

我的schema.rb

ActiveRecord::Schema.define(version: 20150213030338) do

  create_table "shows", force: :cascade do |t|
    t.text     "artist"
    t.datetime "doors_open"
    t.datetime "dinner_starts"
    t.datetime "dinner_ends"
    t.datetime "show_starts"
    t.datetime "show_ends"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
  end

end

1 个答案:

答案 0 :(得分:1)

首先,我更喜欢使用nested_forms。导致节目有艺术家(显示=&gt;(1)(艺术家),如果您想将艺术​​家实施为节目形式,您应该使用嵌套形式方法

class Artist < ActiveRecord::Base
  belongs_to :show
end
class Show < ActiveRecord::Base
  has_one :artist

  accepts_nested_attributes_for :artist
end

用于控制器显示

  def new
    @show = Show.new
    @artist = @show.build_artist
  end
  def show_params
    params.require(:show).permit(:show_date, :doors_open, :doors_end, :show_start, :show_ends, :dinner_opens, :dinner_ends, 
        :artist_attributes => [:id, :name])
  end

和Shows / _form.html.erb

<%= form_for(@show) do |f| %>
  <% if @show.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@show.errors.count, "error") %> prohibited this show from being saved:</h2>

      <ul>
      <% @show.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.fields_for :artist do |artist_builder| %>
  <div class="field">
    <%= artist_builder.label :name %>
    <%= artist_builder.text_field :name %>
  </div>
  <% end %>

  <div class="field">
    <%= f.label :show_date %><br>
    <%= f.datetime_select :show_date %>
  </div>
  <div class="field">
    <%= f.label :doors_open %><br>
    <%= f.time_select :doors_open %>
  </div>
  <div class="field">
    <%= f.label :doors_end %><br>
    <%= f.time_select :doors_end %>
  </div>
  <div class="field">
    <%= f.label :show_start %><br>
    <%= f.time_select :show_start %>
  </div>
  <div class="field">
    <%= f.label :show_ends %><br>
    <%= f.time_select :show_ends %>
  </div>
  <div class="field">
    <%= f.label :dinner_opens %><br>
    <%= f.time_select :dinner_opens %>
  </div>
  <div class="field">
    <%= f.label :dinner_ends %><br>
    <%= f.time_select :dinner_ends %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

您还可以创建模型门和晚餐并应用嵌套表单。但是,让我们保持简单。

同样,对于迁移,请使用time代替datetime

  def change
    create_table :shows do |t|
      t.datetime :show_date
      t.time :doors_open
      t.time :doors_end
      t.time :show_start
      t.time :show_ends
      t.time :dinner_opens
      t.time :dinner_ends

      t.timestamps
    end

希望有所帮助