Absolutely stuck trying to create a nested association in rails form with has_many via

I posted an earlier question about this, and I was encouraged to read a lot of relevant information. I read it and tried to implement about 30 different solutions. None of them worked for me.

Here is what I have.

I have a Miniatures model. I have a model manufacturers. Thumbnails have many manufacturers VIA model Productions.

It seems that the associations are set up correctly, as I can show them in my views and create them through the console. Where I have a problem, you can allow the creation and updating of Miniatures NEW and EDIT views in the Productions table.

The command @miniature.productions.create(manufacturer_id: 1) works in the console, which makes me believe that I should do the same in the form.

I THINK that my problem is always in the Miniatures controller and, in particular, in the CREATE function. I tried a ton of other solutions for people there, and nobody did it. It is also possible that my box for things in my form is wrong, but it seems less problematic.

I have been stuck with this for several days, and although there are other things that I could work on if this connection is not possible, I will need to review my entire application.

The form now creates a row in the Productions table, but does not include all important manufacturer files.

Any help is VERY appreciated.

My new miniature form

 <% 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> 

Thumbnail controller

 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 

Miniature model

 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 

Production model

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

Manufacturer model

 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 
+6
source share
1 answer

Instead of calling:

 @production = @miniature.productions.create 

Rails 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 

Using the build method, the ActiveRecord Autosave Association function is used.

See http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html

You also need to update your params method, for example.

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

Also your file_fields should be multiple (I think) ...

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

Source: https://habr.com/ru/post/955424/


All Articles