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
但每当我尝试创建一个新活动时,我都会收到错误消息“Timeslots活动必须存在”。
我觉得它在创建活动之前尝试为时间段分配activity_id,但我不确定。我已经尝试了很多东西(其中一些我已经在评论表单中包含在我的例子中)但是我无法弄清楚为什么我会收到这个错误。
更新:添加错误日志
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 :(得分: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