在一个控制器中为两个不同的表创建记录被认为是不好的做法吗?

时间:2015-09-23 23:01:08

标签: ruby-on-rails ruby-on-rails-4

我有一个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

2 个答案:

答案 0 :(得分:0)

它不会打扰我,但有些人不喜欢它。虽然上面的内容相当简单,但如果它变得更复杂呢?如果您需要从其他地方执行相同的操作(某些后台任务,通过API,您可能无法执行控制器操作的任何地方),该怎么办?这是不这样做的主要原因。

要问几个问题:

  • 创建活动后,总是创建约会吗?
  • 你是否想从其他地方做同样的事情(比如。控制台,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处的新记录。

此处的最佳做法:

  1. 仅允许用户必须提供的字段。 more
  2. EventsController createEvent使用RESTFul操作。在路线resources关键字处创建所有其余的操作:some example of restful
  3. 按照惯例,让Rails完成工作。