2015-02-14 7 views
0

У меня есть модель, которая имеет несколько полей datetime, все из которых имеют одинаковую дату, но в разное время. Поэтому в моей форме для этой модели я прошу дату один раз, а затем попрошу время для каждого из других, чтобы избежать повторения одной и той же даты снова и снова.Создать добавляет запись в таблицу несколько раз

Как только моя форма возвращает хэш-код params на мой контроллер, у меня есть функция add_date_to_time, которая проходит через каждый ключ и устанавливает его значение даты, введенное ранее в форме. Затем предполагается удалить ключи даты из хэша и не будет - любой ввод, насколько это происходит, будет оценен по достоинству.

Есть две большие проблемы, я бегу в:

1) Самый важный из них - это создает запись в 7 раз. Поэтому, если я добавляю шоу, это шоу добавляется к базе данных 7 раз, а не к одному. Кроме того, после того, как я ударил submit в форме, когда возвращаюсь к показательному индексу, он говорит, что никаких данных не получено. Если я перезагружу его, страница появится правильно.

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 
+0

Hi Thom! как выглядит ваша схема для showcontroller –

+0

thnks @ThomYorkkke, Пожалуйста, пройдите меня через вашу модель. Я не понимаю, почему так много «door_opens» (...). Не могли бы вы сказать, что на Шоу много художников. и у каждой из них есть: start_time и: end_time &&, каждый из которых имеет время_узлы_старт_time и lunch_end_time. –

+0

Итак, дверь в шоу открывается в определенное время, затем начинается ужин, затем обед заканчивается, затем начинается шоу, после чего шоу заканчивается. У шоу также есть только один художник. – ThomYorkkke

ответ

1

Во-первых, я предпочитаю использовать nested_forms. Причина шоу имеет Artist (Показать => (1) (Исполнитель), и если вы хотите реализовать Artist в форме шоу вы должны использовать nested_form подход

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 

и для шоу/_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 

надеюсь, что это помогает

+0

Это было очень полезно. Большое спасибо! Вы были спотыканием о том, чтобы просто делать другие вещи, а не временами. – ThomYorkkke

Смежные вопросы