2016-09-25 10 views
0

Приложение My Rails 5 включает в себя две модели: Activity и Timeslot.Как получить эту вложенную форму для создания нового объекта

activity.rb

class Activity < ApplicationRecord 
    belongs_to :club 
    has_many :timeslots, :dependent => :destroy 
    accepts_nested_attributes_for :timeslots 
    validates :club_id, presence: true 
    validates :name, presence: true, length: { maximum: 50 } 
end 

timeslot.rb

class Timeslot < ApplicationRecord 
    belongs_to :activity 
    validates :time_start, presence: true 
    validates :time_end, presence: true 
    validates :day, presence: true 
    #validates :activity_id, presence: true (I realised this was causing one of the errors I had) 
    default_scope -> { order(day: :asc) } 
end 

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

new.html.erb

<%= form_for(@activity) do |f| %> 
    <%= render 'shared/error_messages', object: f.object %> 
    <div class="field"> 
     <%= f.label :name, "Class name" %>* 
     <%= f.text_field :name, class: 'form-control' %> 

      <%= f.fields_for :timeslots do |timeslots_form| %> 
        <%= timeslots_form.label :time_start, "Start time" %> 
        <%= timeslots_form.time_select :time_start %> 

        <%= timeslots_form.label :time_end, "End time" %> 
        <%= timeslots_form.time_select :time_end %> 

        <%= timeslots_form.label :day %> 
        <%= timeslots_form.select :day, (0..6).map {|d| [Date::DAYNAMES[d], d]} %> 
      <% end %> 
    </div> 
    <%= f.submit "Create class", class: "btn btn-primary" %> 
<% end %> 

Моя версия редактировать/обновить это, кажется, работает хорошо.

activities_controller.rb

class ActivitiesController < ApplicationController 
... 

def new 
    @activity = Activity.new 
    @activity.timeslots.build 
end 

def create 
    @activity = current_club.activities.build(activity_params) 
    #@activity.timeslots.first.activity_id = @activity.id (I thought this might solve the problem, but didn't) 
    if @activity.save 
     flash[:success] = "New class created!" 
     redirect_to activities_path 
    else 
     render 'new' 
    end 
end 

def edit 
    @activity = current_club.activities.find_by(id: params[:id]) 
    @activity.timeslots.build 
end 

def update 
    @activity = current_club.activities.find_by(id: params[:id]) 
    if @activity.update_attributes(activity_params) 
     flash[:sucess] = "Class updated!" 
     redirect_to edit_activity_path(@activity) 
    else 
     render 'edit' 
    end 
end 
... 

private 

    def activity_params 
     params.require(:activity).permit(:name, :active, #active is set to default: true 
             :timeslots_attributes => [:id, 
                    :time_start, 
                    :time_end, 
                    :day, 
                    :active]) 
    end 
end 

Но всякий раз, когда я пытаюсь создать новый вид деятельности, я получаю сообщение «Таймслоты должны существовать виды деятельности» ошибок.

Я чувствую, что он пытается назначить Activity_id для временного интервала перед созданием активности, но я не уверен. Я пробовал много вещей (некоторые из которых я включил в мой пример в форме комментариев), но я не могу понять, почему я получаю эту ошибку.

Update: Добавить журнал ошибок

Started POST "/activities" for 127.0.0.1 at 2016-09-25 18:04:51 +0700 
Processing by ActivitiesController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"xp+dBcWC4cjI6FLpIqhU0RzM4ldZ4JpkFLSyAXcmifL73QqWz6R65EHm/Tj7QxlXnWiBA0axjVXvMZHQ+XKA9A==", "activity"=>{"name"=>"Newest class", "timeslots_attributes"=>{"0"=>{"time_start(1i)"=>"2016", "time_start(2i)"=>"9", "time_start(3i)"=>"25", "time_start(4i)"=>"12", "time_start(5i)"=>"00", "time_end(1i)"=>"2016", "time_end(2i)"=>"9", "time_end(3i)"=>"25", "time_end(4i)"=>"13", "time_end(5i)"=>"30", "day"=>"4"}}}, "commit"=>"Create class"} 
    Club Load (0.2ms) SELECT "clubs".* FROM "clubs" WHERE "clubs"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] 
    (0.1ms) begin transaction 
    (0.1ms) rollback transaction 
    Rendering activities/new.html.erb within layouts/application 
    Rendered shared/_error_messages.html.erb (1.5ms) 
    Rendered activities/new.html.erb within layouts/application (16.9ms) 
    Rendered layouts/_rails_default.html.erb (58.5ms) 
    Rendered layouts/_shim.html.erb (0.5ms) 
    Rendered layouts/_header.html.erb (1.7ms) 
    Rendered layouts/_footer.html.erb (0.8ms) 
Completed 200 OK in 111ms (Views: 93.9ms | ActiveRecord: 0.3ms) 
+0

Показать свой полный журнал ошибок с вашей terminal – luissimo

+0

Обновлен мой вопрос, чтобы включить журнал ошибок – Rhys0h

+0

Где ошибка, свидетелем которой вы являетесь, поскольку в журнале не отображаются какие-либо ошибки, и ваш код кажется прекрасным? – luissimo

ответ

0

Вы получаете эту ошибку, потому что Rails 5 делает belongs_to атрибута требуется по умолчанию. Кроме того, механизм экономии вид следующим образом:

validate your parent model 
validate your child model # validation fails here because parent doesn't have an id yet, because it hasn't been saved 
save parent model 
save child model 

Способ решения этой проблемы заключается в следующем:

class Activity < AR 
    has_many :timeslots, dependent: :destroy, inverse_of: :activity 
    accepts_nested_attributes_for :timeslots 
end 

class Timeslot < AR 
    belongs_to :activity, inverse_of: :timeslot 
end 

Вы можете узнать больше об этом here и here

+0

Благодарим вас за ответ. Форма теперь работает. Вторая ссылка, которую вы указали, касалась конкретной проблемы, с которой я столкнулся. – Rhys0h

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

  • Нет связанных вопросов^_^