2016年7月5日 星期二

Rails 嵌套表單

這是我第一次在實戰中使用嵌套表單,把一些心得紀錄下來。

為什麼要使用嵌套表單

在我實作的Web App中,會先建立一個計劃,然後才會去建立計劃的提醒方式,而計劃與提醒方式是一對一的關係,其實就資料結構來說,計劃與提醒方式是可以做在同一個Model(Table)中的,只是為什麼不這樣做,一方面是規劃的操作流程的關係,一方面也是我的M屬性發作想自我學習挑戰。所以為了不要另外增加一個提醒方式的Controller,才會需要使用嵌套表單來實作。


規劃的系統流程


因為要建立計劃附屬事項的關係,所以必須先建立計劃(Master),待完成附屬事項(Detail)完成後才去建立計劃提醒,因此這樣的作法與原先在上xdite的課程時嵌套的內容與Master一起建立有一點點的不同。

開始實作


Model

在這個案例中有兩個Model,分別是Project與NotifyMethod,兩者的關係是一對一的關係

class Project < ActiveRecord::Base
  has_one :notify, class_name:"NotifyMethod", dependent: :destroy
  accepts_nested_attributes_for :notify, :reject_if=>:all_blank  #加入notify到嵌套中
end

class NotifyMethod < ActiveRecord::Base
  belongs_to :project  
end

Controller

這次是在Project已經建立後才又去維護提醒方式,所以等於是在執行update action,也因為再第一次維護notify時,notify還是空的,所以需要先build_notify
class ProjectsController < ApplicationController
...略
  def wizard
    @project = Project.find(params[:id])
    #因為notify還是空的所以先build一個殼出來,後面的if是先檢查notify是否已經存在了,避免每次進來都重新build
    @project.build_notify if @project.notify.nil?
    @real_lives = @project.real_lives.all
    @progresses = @project.progresses
    @editable = true
  end
  def update
    @project = Project.find(params[:id])
    if @project.update(project_params) then
      redirect_to projects_path
    else
      redirect_to :wizard
    end
  end
  private
  def project_params
    params.require(:project).permit(:target, :subtarget, :success_define, :possible,
                                    notify_attributes:[:email])
  end
end

View



沒有留言: