has_many:通过关联 - 在创建操作期间无法使用外部ID保存记录

时间:2014-01-30 23:58:47

标签: ruby-on-rails foreign-keys has-many-through strong-parameters

我有一个Rails 4应用程序,并且在创建has_many的新记录时遇到问题:通过关联。我在调试时做了几点观察:

  1. 注释掉与功能模型关联的复选框,应用程序将正确创建和保存场地对象。
  2. 场地控制器中的更新操作适用于功能复选框。
  3. 有人可以告诉我为什么我的应用程序在创建新场地时保存相关功能对象(数组)时遇到问题?不确定这是否是因为在保存之前外键key_id不存在...

    以下是代码:

    venues.rb

    class Venue < ActiveRecord::Base
      has_many :venue_features, dependent: :destroy
      has_many :features, :through => :venue_features
    

    venue_features.rb

    class VenueFeature < ActiveRecord::Base
      belongs_to :venue
      belongs_to :feature
    

    features.rb

    class Feature < ActiveRecord::Base
      has_many :venue_features, dependent: :destroy
      has_many :venues, :through => :venue_features
    

    场地\ new.html.erb (功能列为复选框 - 使用选择相关复选框)

    <%= hidden_field_tag "venue[feature_ids][]", nil %>
    <% Feature.all.each do |feature| %>
      <div class="checkbox">
        <label>
          <%= check_box_tag "venue[feature_ids][]", feature.id, @venue.feature_ids.include?(feature.id) %>
          <%= feature.name %><br>
        </label>
      </div>
    <% end %>
    

    venues_controller.rb

    class VenuesController < ApplicationController
      def create
        @venue = Venue.new(venue_params)
    
        if @venue.save(venue_params)
          flash[:success] = "Success!"
          redirect_to venues_path
        else
          flash[:error] = "Problem!"
          render 'new'
        end
      end
    
      def venue_params
        params.require(:venue).permit(:attribute_1, :attribute_2, :feature_type_ids => [])
      end
    end 
    

1 个答案:

答案 0 :(得分:0)

我确信有一个更清洁的解决方案,但我最终做的是在成功保存后更新一组不同的强参数。问题概率与1)我的一个参数:feature_type_ids实际上是一个数组和/或2):feature_type_ids在不同的模型(不是venues.rb)中。我认为Rails会“自动”处理对不同模型的保存,因为venues.rb和features.rb已经通过:has_many:through relationship建立了。我很想要一个更好的解决方案,但以下工作:

class VenuesController < ApplicationController
  def create
    ...
    if @venue.save(venue_only_params)
      if @venue.update_attributes(venue_params)
      flash[:success] = "Success!"
      redirect_to venues_path
    else
      flash[:error] = "Problem!"
    render 'new'
    end
  end

  def venue_params
    params.require(:venue).permit(:attribute_1, :attribute_2, :feature_type_ids => [])
  end

  def venue_only_params
    params.require(:venue).permit(:attribute_1, :attribute_2)
  end

end