Rails在同一模型

时间:2017-06-30 11:34:34

标签: ruby-on-rails ruby forms ruby-on-rails-5 nested-attributes

尝试实现类似SO question

的内容

我认为我的意图最好用一个简单的例子来解释。让我们说,我有三个值(同一模型的所有对象,比如Users),"彼得","约翰"和" Thurse"。 我希望我的表单包含两个字段:regular_user:commander_user。对于这两个字段,我想从模型User中进行选择(因此,select_tags都应包含相同的值 - Peter,John和Thurse)。所以我的目标是为常规用户选择彼得和约翰,为指挥官选择Thurse。 另外,我们假设表单适用于模型Game。在这种情况下,绑定模型将是GameUser。 基本上我想要的是致电my_game.regular_users并接收"彼得"和"约翰"并致电my_game.commanders并接收" Thurse"。

我的实际结构的字描述如下:我有菜单(如在餐馆),每个菜单可以有不同数量的人。此模型名为Personamount,它们通过Menupersonamounthas_many through关系连接。

适用于一个领域。但我需要以相同的形式保存Personamount中的一些不同条目。

以下是代码:

形式:

 .row
      .col-md-12
            / Select for how many persons this menu can be bought for
            .section.row
              %label.field.prepend-field
                =f.collection_select(:personamount_ids, Personamount.all, :id, :title, {include_blank: false, :include_hidden => false, :selected => @menu.personamounts.map(&:id)}, { class: 'select2-multiple form-control select-info select-personamount', :multiple => true})

        .row
          .col-sm-12
            .section.row
              %label.field.prepend-field
                =f.collection_select(:bonus_personamount_ids, Personamount.all, :id, :title, {include_blank: false, :include_hidden => false}, { class: 'select2-multiple form-control select-info select-bonus-personamount', :multiple => true})

Menu.rb:

class Menu < ActiveRecord::Base
  has_many :menupersonamounts, dependent: :destroy
  has_many :personamounts, through: :menupersonamounts
  has_many :bonus_personamounts, through: :menupersonamounts, :class_name  => "Personamount", :foreign_key => :bonus_personamount_id
end

Menupersonamount.rb:

class Menupersonamount < ApplicationRecord
  belongs_to :menu
  belongs_to :personamount, :class_name  => "Personamount", :foreign_key => :personamount_id
  belongs_to :bonus_personamount, :class_name  => "Personamount", :foreign_key => :bonus_personamount_id
end

Personamount.rb:

class Personamount < ApplicationRecord
    has_many :menupersonamounts, dependent: :destroy
  has_many :menus, through: :menupersonamounts

  has_many  :dinner_amount_options, dependent: :destroy
  accepts_nested_attributes_for :dinner_amount_options, allow_destroy: true
end

这是我的错误:

ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR:  insert or update on table "menupersonamounts" violates foreign key constraint "fk_rails_d94bf3abd0"
DETAIL:  Key (bonus_personamount_id)=(13) is not present in table "bonus_personamounts".
: INSERT INTO "menupersonamounts" ("menu_id", "created_at", "updated_at", "bonus_personamount_id") VALUES ($1, $2, $3, $4) RETURNING "id"):

app/controllers/admin/menus_controller.rb:33:in `update'

嗯,显而易见的是,没有表格bonus_personamounts,但如果我将foreign_key_idbonus_personamount_id更改为personamount_id,表单只会保存两个相同的价值观。

所以,再次 - 我需要将同一个表Personamount中的值保存到一个表单中的两个不同字段中。

更新1:

Menu.rb

class Menu < ActiveRecord::Base
  has_many :menupersonamounts, dependent: :destroy
  has_many :bonusmenupersonamounts, dependent: :destroy, class_name: "Menupersonamount", foreign_key: :bonuspersonamount_id

  has_many :personamounts, through: :menupersonamounts
  has_many :bonuspersonamounts, through: :bonusmenupersonamounts
end

Personamount.rb

class Personamount < ApplicationRecord
    has_many :menupersonamounts, dependent: :destroy
  has_many :bonusmenupersonamounts, :class_name => 'Menupersonamount', :foreign_key => :bonuspersonamount_id

  has_many :menus, through: :menupersonamounts
  has_many :menus, through: :bonusmenupersonamounts

  has_many  :dinner_amount_options, dependent: :destroy
  accepts_nested_attributes_for :dinner_amount_options, allow_destroy: true
end

Menupersonamount.rb

class Menupersonamount < ApplicationRecord
  belongs_to :menu
  belongs_to :personamount
  belongs_to :bonuspersonamount, :class_name  => "Personamount", foreign_key: :bonuspersonamount_id
end

menus_controller.rb

def update
    if @menu.update(menu_params)
        redirect_to edit_admin_menu_path(@menu), method: :get
        flash[:success] = "Updated!"
    else
        render "edit"
    end
end

private

def menu_params
    params.require(:menu).permit(:category_id, :price, :daterange, :hotpic, :remove_hotpic,
        { delivery_ids: [] }, { recipe_ids: [] }, { personamount_ids: [] }, { bonuspersonamount_ids: [] }, { day_ids: [] }, :change_from, 
        :change_to, :description, :has_dessert, :has_breakfast,
  menurecipes_attributes: [:id, :sortable, :menu_id, :recipe_id, :_destroy, recipe_attributes: [:id, :_destroy]]

  )
end

1 个答案:

答案 0 :(得分:0)

我想我现在明白了这个问题。你有一个类菜单,它有多个Menuspersonamounts。 Menupersonamounts可以容纳一个personamounts和一个bonuspersonamount,如果它们是连续创建的,则没有问题。

它也只适用于一个字段,因为如果设置多个personamounts(例如),则rails会创建n(在示例2中)Menupersonamounts个记录:

Menupersonamounts1: { personamounts: 1 }
Menupersonamounts2: { personamounts: 2 }

现在让我们假设我们提交相同的两个personamounts(1,2)和bonuspersonamount(1)。现在无法确定如何保存:

Menupersonamounts1: { personamounts: 1, bonuspersonamounts: 1 }
Menupersonamounts2: { personamounts: 2 }

或者:

Menupersonamouns1: { personamounts: 1 }
Menupersonamount2: { personamounts: 2, bonuspersonamounts: 1 }

选择的ID越多越好。所以有两种可能性。自己处理id的映射,或者连续处理Menupersonamounts创建,这样就可以选择一个personamount和一个bonuspersonamount