微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rails has_many:通过具有简单形式的嵌套形式

如何解决Rails has_many:通过具有简单形式的嵌套形式

我正在尝试制作一个玩家角色生成器。我有一个表格,希望可以让我将技能及其价值附加到角色表模型上。我制作了这样的模型:

class CharacterSheet < ApplicationRecord
  has_many :character_sheet_skills,dependent: :destroy
  has_many :skills,through: :character_sheet_skills
  belongs_to :user

  accepts_nested_attributes_for :skills
end

class Skill < ApplicationRecord
  has_many :character_sheet_skills,dependent: :destroy
  has_many :character_sheets,through: :character_sheet_skills

  attr_reader :value
end

class CharacterSheetSkill < ApplicationRecord
  belongs_to :skill
  belongs_to :character_sheet
end

角色表模型包含有关玩家角色的数据,技能模型具有游戏中所有可用的技能。我想在CharacterSheetSkill中存储玩家为角色选择的技能以及设置技能值的整数字段。

打开表格时,我已经拥有数据库的完整技能列表。我要做的就是创建一个字符表,该表具有所有这些技能并具有附加值。我尝试在表单中使用“ fields_for”,但无法真正使用它。现在看起来像这样:

<%= simple_form_for [@user,@sheet] do |f| %>
    <%= f.input :name %>
    <%= f.input :experience,readonly: true,input_html: {'data-target': 'new-character-sheet.exp',class: 'bg-transparent'} %>
...
    <%= f.simple_fields_for :skills do |s| %>
      <%= s.input :name %>
      <%= s.input :value %>
    <% end %>
<% end %>

如何制作该表单,以便将角色表与CharacterSheetSkills一起保存?

解决方法

一个更好的主意是将skills用作规范化表,在其中存储技能的“主”定义,例如名称和说明。

class CharacterSheetSkill < ApplicationRecord
  belongs_to :skill
  belongs_to :character_sheet
  delegate :name,to: :skill
end

然后使用fields_for :character_sheet_skills在连接表上显式创建行:

<%= f.fields_for :character_sheet_skills do |cs| %>
  <fieldset>
    <legend><%= cs.name %></legend>
    <div class="field">
      <%= cs.label :value %>
      <%= cs.number_field :value %>
    </div>
    <%= cs.hidden_field :skill_id %>
  </fieldset>
<% end %>

如果要让用户选择技能,则可以使用select代替隐藏字段。

当然,除非您“输入”输入内容,否则什么都不会显示:

class CharacterSheetController < ApplicationController
  def new
    @character_sheet = CharacterSheet.new do |cs|
      # this seeds the association so that the fields appear
      Skill.all.each do |skill|
        cs.character_sheet_skills.new(skill: skill)
      end
    end
  end

  def create
    @character_sheet = CharacterSheet.new(character_sheet_params)
    if @character_sheet.save
      redirect_to @character_sheet
    else
      render :new
    end
  end

  private
  def character_sheet_params
    params.require(:character_sheet)
          .permit(
             :foo,:bar,:baz,character_sheet_skill_attributes: [:skill_id,:value]
          )
  end
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。