我有一个has_many通过关联,差不多exactly like this one from the documentation我尝试创建events
并通过名为users
的表将事件链接到appointments
。下面的代码(我的尝试)对于必须一次更新两个表的问题似乎是一个相当不错的解决方案,但我不是100%确信它是正确的,因为我在约会控制器内创建一个事件而不是在事件控制器中。在表连接的情况下是否可以,或者它被视为不良做法?
......如果被认为是不好的做法,请尽可能分享替代解决方案。谢谢。
班级:
class AppointmentsController < ApplicationController
行动:
def create
@event = Event.create(appointment_params[:event_id])
Appointment.create({user_id: @current_user.id, event_id: @event.id})
redirect_to action: 'index'
end
我的预约_params:
def appointment_params
params.require(:appointment).permit(:user_id, event_id: [:id, :location, :time, :subject, :created_at, :updated_at ])
end
答案 0 :(得分:0)
它不会打扰我,但有些人不喜欢它。虽然上面的内容相当简单,但如果它变得更复杂呢?如果您需要从其他地方执行相同的操作(某些后台任务,通过API,您可能无法执行控制器操作的任何地方),该怎么办?这是不这样做的主要原因。
要问几个问题:
如果是这样,根据你回答问题的方式,你有几个选择。
如果你总是这样做,你可以在Event上使用回调来创建约会。回调是有些人不喜欢的另一件事,但在这里有道理。
在Event上定义create_with_appointment
方法并将逻辑放在那里。
创建一个服务对象来处理它。
答案 1 :(得分:0)
似乎这段代码需要一些重构,让我们这样做:
首先:你允许一个完全没有使用的user_id:
参数。因为您使用的是@current_user.id
。您可以从允许的参数(以及表格)中删除此字段。
现在,您只需要允许event_id:
对象。使用该名称,它必须是ID,而不是模型对象。通常你会看到event_attributes
之类的东西(使用嵌套属性)。但是,如果控制器收到的所有数据都是针对某个事件的,那么它必须位于EventsController
而不是AppointmentsController
。您需要将此操作移动到EventsController。
class EventsController < ApplicationController
def create
@event = Event.new(event_params)
@event.users << @current_user
if @event.save
redirect_to @event
else
render :new
end
end
private
def event_params
params.require(:event).permit(:location, :time, :subject)
end
end
我确实删除了字段:id
,:created_at
和:updated_at
,因为它们不需要,时间戳由Rails自动管理。
通过此控制器操作,将添加Appointments
处的新记录。
此处的最佳做法:
EventsController
create
和Event
使用RESTFul操作。在路线resources
关键字处创建所有其余的操作:some example of restful。按照惯例,让Rails完成工作。