has_many :通过不创建我的第三个模型
has_many :through not creating my third model
我正在构建一个基于位置的应用程序,并注意到一些奇怪的行为。我的模型如下:
class User < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :events, through: :attendances
class Event < ActiveRecord::Base
acts_as_mappable :lat_column_name => :latitude,
:lng_column_name => :longitude
has_many :attendances, dependent: :destroy
has_many :users, through: :attendances
class Attendance < ActiveRecord::Base
belongs_to :user
belongs_to :event
所以问题是,在创建新事件时,我首先有 user.events.new(params)
然后我有一个 if 语句来检查新事件是否正确保存,所以 if event.save #do stuff.
当我这样做时这样,将 user
连接到新创建的 event
的 Attendance
模型未创建,而如果我有 user.events.create(params),
,则会成功创建新的 Attendance
。这是正常的吗?在这种情况下我必须使用 user.events.create
吗?为什么在我 user.events.new
然后 event.save
时没有创建新的 Attendance
?
编辑:从 events_controller.rb
添加了 Create
方法:
def create
if params[:username] && params[:password]
username = params[:username]
password = params[:password]
user = User.find_by(username: username)
if user
if user.authenticate(password)
event_title = params[:title]
event_date = Date.parse(params[:date])
event_description = params[:description]
latitude = params[:latitude]
longitude = params[:longitude]
event = user.events.new(title: event_title, date: event_date, description: event_description, latitude: latitude,
longitude: longitude)
if event.save
render :json => {id: event.id, title: event.title, date: event.date, description: event.description, latitude: event.latitude,
longitude: event.longitude
}
else
error_message(event.errors.full_messages)
end
#attendance = Attendance.find_by(user_id: user.id, event_id: event.id)
#attendance.update_attribute(:host, 1)
else
error_message("Authentication failed. Please login, or sign up.")
end
else
error_message("Username not recognized. Make sure username is right, or sign up.")
end
else
not_found
end
end
通常我会在模型中使用 accepts_nested_attributes_for
。然后使用 .build
方法将它们保存在创建操作中。
这里有一些可能对您有帮助的链接:
Association Methods and Rails Casts: Nested Forms(对accepts_nested_attributes_for方法的解释很好。)
希望对您有所帮助
此行为是预期的,这是一个众所周知的问题。幸运的是它有一个解决方案。尝试将 inverse_of
参数添加到您的 belongs_to 关联中:
class Attendance < ActiveRecord::Base
belongs_to :user, inverse_of: :attendances
belongs_to :event, inverse_of: :attendances
end
您可以在此处阅读有关此问题的更多信息:Link
方案二:
您也可以将您的控制器代码更改为:
event = Event.new(...event_params...)
if event.save
user.events << event
render :json => {...}
else
...
我正在构建一个基于位置的应用程序,并注意到一些奇怪的行为。我的模型如下:
class User < ActiveRecord::Base
has_many :attendances, dependent: :destroy
has_many :events, through: :attendances
class Event < ActiveRecord::Base
acts_as_mappable :lat_column_name => :latitude,
:lng_column_name => :longitude
has_many :attendances, dependent: :destroy
has_many :users, through: :attendances
class Attendance < ActiveRecord::Base
belongs_to :user
belongs_to :event
所以问题是,在创建新事件时,我首先有 user.events.new(params)
然后我有一个 if 语句来检查新事件是否正确保存,所以 if event.save #do stuff.
当我这样做时这样,将 user
连接到新创建的 event
的 Attendance
模型未创建,而如果我有 user.events.create(params),
,则会成功创建新的 Attendance
。这是正常的吗?在这种情况下我必须使用 user.events.create
吗?为什么在我 user.events.new
然后 event.save
时没有创建新的 Attendance
?
编辑:从 events_controller.rb
添加了 Create
方法:
def create
if params[:username] && params[:password]
username = params[:username]
password = params[:password]
user = User.find_by(username: username)
if user
if user.authenticate(password)
event_title = params[:title]
event_date = Date.parse(params[:date])
event_description = params[:description]
latitude = params[:latitude]
longitude = params[:longitude]
event = user.events.new(title: event_title, date: event_date, description: event_description, latitude: latitude,
longitude: longitude)
if event.save
render :json => {id: event.id, title: event.title, date: event.date, description: event.description, latitude: event.latitude,
longitude: event.longitude
}
else
error_message(event.errors.full_messages)
end
#attendance = Attendance.find_by(user_id: user.id, event_id: event.id)
#attendance.update_attribute(:host, 1)
else
error_message("Authentication failed. Please login, or sign up.")
end
else
error_message("Username not recognized. Make sure username is right, or sign up.")
end
else
not_found
end
end
通常我会在模型中使用 accepts_nested_attributes_for
。然后使用 .build
方法将它们保存在创建操作中。
这里有一些可能对您有帮助的链接: Association Methods and Rails Casts: Nested Forms(对accepts_nested_attributes_for方法的解释很好。)
希望对您有所帮助
此行为是预期的,这是一个众所周知的问题。幸运的是它有一个解决方案。尝试将 inverse_of
参数添加到您的 belongs_to 关联中:
class Attendance < ActiveRecord::Base
belongs_to :user, inverse_of: :attendances
belongs_to :event, inverse_of: :attendances
end
您可以在此处阅读有关此问题的更多信息:Link
方案二:
您也可以将您的控制器代码更改为:
event = Event.new(...event_params...)
if event.save
user.events << event
render :json => {...}
else
...