如何填充外键

时间:2015-10-31 19:46:28

标签: ruby-on-rails activerecord

我正在尝试在表单中填充一组动态属性值,但我遇到了问题。我有一个如下所示的数据模型: enter image description here

模型定义如下:

class Item < ActiveRecord::Base
    belongs_to :collection
    has_many :item_instances, :dependent => :destroy, :inverse_of => :item
    has_many :item_attribute_values
    has_many :item_attributes, :through => :item_attribute_values
    has_many :item_attributes, :through => :collection
    accepts_nested_attributes_for :item_instances
    accepts_nested_attributes_for :item_attribute_values
    accepts_nested_attributes_for :item_attributes


    validates :name, :presence => true, length: { maximum: 50 }
    validates :collection, :presence => true

    def self.find_item(user, collection_id, item_id)
        user.collections.find(collection_id).items.find_by_id(item_id)
    end
end

class ItemAttributeValue < ActiveRecord::Base
   belongs_to :item_attribute
   belongs_to :item
   attr_accessor :attribute_name

   accepts_nested_attributes_for :item_attribute

   validates_presence_of :item_attribute_id

end

class ItemAttribute < ActiveRecord::Base
  belongs_to :collection
  has_many :item_attribute_values
  has_many :items, :through => :item_attribute_values

end

class Collection < ActiveRecord::Base
    has_many    :collection_instances
    has_many    :users, :through => :collection_instances
    has_many    :items
    has_many    :item_attributes
end

控制器如下。我已经排除了任何不相关的代码。

class ItemsController < ApplicationController
    before_action :authenticate_user!
    before_filter(:only => [:toggle_item_owned_state, :update, :create]) do
        @collection = current_user.collections.find_by_id(params[:collection_id])
        @c_instance = @collection.collection_instances.where(:user => current_user).take
        @items = @collection.items
    end

    before_filter(:only => [:toggle_item_owned_state, :show, :new, :edit]) do
        @c_instance = current_user.collection_instances.find_by_id(params[:mycollection_id])
        @collection = current_user.collections.find(@c_instance.collection_id)
        @items = @collection.items

    end

    def new
        @item = Item.new collection_id: @collection.id
        @item_attributes = @collection.item_attributes
        @item_instance = @item.item_instances.build(:owned => true, 
            :user => current_user, :item => @item, 
            :collection_instance => @collection.collection_instances.where(:user => current_user).take)

        @item_attributes.each do |ia|
            iav = @item.item_attribute_values.build(:item_attribute_id => ia.id, :attribute_name => ia.name)
        end

        render 'mycollections/show'
    end

    def create
        my_params = item_params
        @item = @collection.items.build(my_params)

        if @item.save!
            redirect_to mycollection_item_path(:mycollection_id => @c_instance.id, :id => @item.id)
        else
            flash.now[:alert] = "There was a problem saving this item."
            render 'mycollections/show'
        end
    end

    def item_params
        params.require(:item).permit(:name, :description,
            item_instances_attributes: [:id, :owned, :user, :item],
            item_attribute_values_attributes: [:id, :attribute_name, :value, :item_attribute_id])
    end
end

我的观点如下所示。它基本上是一个表单,可以在一个提交中更新Items和ItemAttributeValues。相关部分位于此代码的底部,并引用屏幕截图中的“自定义属性”部分。

<%= form_for [@collection, @item] do |f| %>
    <div id="basic_information" class="panel panel-default">
        <div class="panel-heading">Basic Information</div>
        <div class="panel-body">
            <div class="row">
                <span class="col-sm-12">
                    <%= render :partial => 'mycollections/basic_information_form', :locals => {:f => f} %>
                </span>
            </div>  
        </div>
    </div>  
    <div id="ownership-details" class="panel panel-default">
        <div class="panel-heading">Ownership Details</div>
        <div class="panel-body">
            <div id="ownership_details">
                <div align="left">      
                    <%= f.fields_for :item_instances, @item_instance do |io| %>
                        <%= io.check_box :owned, :id => 'item_instance_ownership' %> Owned
                    <% end %>
                </div>
            </div>
        </div>
    </div>
    <p />

    <% if not @item_attributes.nil? %>

        <div id="custom-attributes" class="panel panel-default">
          <div class="panel-heading">Custom Attributes</div>
          <div class="panel-body">
            <div id="custom_attributes">
              <% @item.item_attribute_values.each do |iav| %>
                  <%= f.fields_for :item_attribute_values,  iav do  |g| %>
                      <%= iav.attribute_name %>:  <%= g.text_field :value %><br />
                  <% end %>
              <% end %>
            </div>
          </div>
        </div>
    <% end %>
<% end %>

问题 现在,我的问题是每当我提交表单时,ItemAttributeValues表中item_attribute_id的值都是nil。我可以确认,当我在'new'中构建记录时会填充它,但是在'create'中提交和接收的内容缺少该字段。

我可以添加一个隐藏字段并使其工作,但这样就可以打开数据操作。

有人可以提供解决方案或想法,确保在提交表单时确保填充item_attribute_id吗?

为清楚起见,页面的UI看起来像这样:

enter image description here

0 个答案:

没有答案