绝对坚持尝试通过has_many通过rails形式以Rails形式创建嵌套关联 [英] Absolutely stuck trying to create nested association in rails form with has_many through

查看:65
本文介绍了绝对坚持尝试通过has_many通过rails形式以Rails形式创建嵌套关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了一个与此有关的较早的问题,并被建议阅读许多相关信息.我已阅读并尝试实现约30种不同的解决方案.没有一个对我有用.

I posted an earlier question about this and was advised to read lots of relevant info. I have read it and tried implementing about 30 different solutions. None of which have worked for me.

这就是我所拥有的.

我有一个微型模型. 我有一个制造商模型. 微型模型通过生产模型吸引了许多制造商.

I have a Miniatures model. I have a Manufacturers model. Miniatures have many manufacturers THROUGH a Productions model.

关联似乎设置正确,因为我可以在视图中显示它们并通过控制台创建它们.我遇到的问题是让Miniatures NEW和EDIT视图创建并更新到Productions表.

The associations seem to be set up correctly as I can show them in my views and create them via the console. Where I have a problem is in letting the Miniatures NEW and EDIT views create and update to the Productions table.

在控制台中,命令@miniature.productions.create(manufacturer_id: 1)有效,这使我相信我应该能够以表格的形式进行操作.

In the console the command @miniature.productions.create(manufacturer_id: 1) works, which leads me to believe I should be able to do the same in a form.

我认为我的问题始终在微型控制器中,尤其是CREATE函数中.我在那里尝试了许多其他人的解决方案,但没有一个解决之道.表单中的field_for内容也有可能是错误的,但这似乎不太合适.

I THINK my problem is always in the Miniatures Controller and specifically the CREATE function. I have tried out a ton of other peoples solutions there and none have done the trick. It is also possible that my field_for stuff in my form is wrong but that seems less fiddly.

我已经坚持了好几天,尽管我还有其他事情可以做,但是如果无法实现这种关联,那么我需要重新考虑整个应用程序.

I've been stuck on this for days and while there are other things I could work on, if this association isn't possible then I'd need to rethink my entire application.

该表单现在在Productions表中创建一行,但其中不包含所有重要的制造商ID.

The form now creates a line in the Productions table but doesn't include the all important manufacturer_id.

非常感谢任何帮助.

我的新微型表格

<% provide(:title, 'Add miniature') %>
<h1>Add a miniature</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(@miniature) do |f| %>
      <%= render 'shared/error_messages', object: f.object %>
      <%= f.label :name %>
      <%= f.text_field :name %>
       <%= f.fields_for :production do |production_fields| %>
      <%= production_fields.label :manufacturer_id, "Manufacturer" %>
      <%= production_fields.select :manufacturer_id, options_from_collection_for_select(Manufacturer.all, :id, :name) %>
      <% end %>
      <%= f.label :release_date %>
      <%= f.date_select :release_date, :start_year => Date.current.year, :end_year => 1970, :include_blank => true %>

      <%= f.submit "Add miniature", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>

微型控制器

class MiniaturesController < ApplicationController
   before_action :signed_in_user, only: [:new, :create, :edit, :update]
   before_action :admin_user,     only: :destroy

  def productions
    @production = @miniature.productions
  end

  def show
    @miniature = Miniature.find(params[:id])
  end

  def new
    @miniature = Miniature.new 
  end

  def edit
    @miniature = Miniature.find(params[:id])
  end

  def update
    @miniature = Miniature.find(params[:id])
    if @miniature.update_attributes(miniature_params)
      flash[:success] = "Miniature updated"
      redirect_to @miniature
    else
      render 'edit'
    end
  end
  def index
    @miniatures = Miniature.paginate(page: params[:page])
  end

  def create
    @miniature = Miniature.new(miniature_params)
    if @miniature.save
      @production = @miniature.productions.create
      redirect_to @miniature
    else
      render 'new'
    end
  end

  def destroy
    Miniature.find(params[:id]).destroy
    flash[:success] = "Miniature destroyed."
    redirect_to miniatures_url
  end

private
    def miniature_params
      params.require(:miniature).permit(:name, :release_date, :material, :scale, :production, :production_attributes)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end

    def signed_in_user
      unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
      end
    end
end

微型模型

class Miniature < ActiveRecord::Base
  has_many :productions, dependent: :destroy
  has_many :manufacturers, :through => :productions
  accepts_nested_attributes_for :productions

    validates :name, presence: true, length: { maximum: 50 }
    validates :material, presence: true
    validates :scale, presence: true
    validates_date :release_date, :allow_blank => true

  def name=(s)
    super s.titleize
  end

end

生产模型

class Production < ActiveRecord::Base
    belongs_to :miniature
    belongs_to :manufacturer



end

制造商型号

class Manufacturer < ActiveRecord::Base
    has_many :productions
    has_many :miniatures, :through => :productions
    validates :name, presence: true, length: { maximum: 50 }
    accepts_nested_attributes_for :productions
end

推荐答案

而不是调用:

@production = @miniature.productions.create

尝试Rails的构建"方法:

Try Rails' "build" method:

def new
  @miniature = Miniature.new(miniature_params)
  @miniature.productions.build
end

def create
  @miniature = Miniature.new(miniature_params)
  if @miniature.save
    redirect_to @miniature
  else
    render 'new'
  end
end

使用构建方法使用ActiveRecord的自动保存关联功能.

Using the build method uses ActiveRecord's Autosave Association functionality.

请参见 http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

您还需要更新params方法,例如

You also need to update your params method, e.g.

def miniature_params
  params.require(:miniature).permit(:name, :release_date, :material, :scale, productions_attributes: [:manufacturer_id])
end

您的fields_for也应该是复数(我认为)...

Also your fields_for should be plural (I think)...

<%= f.fields_for :productions do |production_fields| %>

这篇关于绝对坚持尝试通过has_many通过rails形式以Rails形式创建嵌套关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆