Absolutely stuck trying to create nested association in rails form with has_many through -


i posted earlier question , advised read lots of relevant info. have read , tried implementing 30 different solutions. none of have worked me.

here's i've got.

i have miniatures model. have manufacturers model. miniatures have many manufacturers through productions model.

the associations seem set correctly can show them in views , create them via console. have problem in letting miniatures new , edit views create , update productions table.

in console command @miniature.productions.create(manufacturer_id: 1) works, leads me believe should able same in form.

i think problem in miniatures controller , create function. have tried out ton of other peoples solutions there , none have done trick. possible field_for stuff in form wrong seems less fiddly.

i've been stuck on days , while there other things work on, if association isn't possible i'd need rethink entire application.

the form creates line in productions table doesn't include important manufacturer_id.

any appreciated.

my new miniature form

<% provide(:title, 'add miniature') %> <h1>add miniature</h1>  <div class="row">   <div class="span6 offset3">     <%= form_for(@miniature) |f| %>       <%= render 'shared/error_messages', object: f.object %>       <%= f.label :name %>       <%= f.text_field :name %>        <%= f.fields_for :production |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> 

miniatures 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 

instead of calling:

@production = @miniature.productions.create 

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 

using build method uses activerecord's autosave association functionality.

see http://api.rubyonrails.org/classes/activerecord/autosaveassociation.html

you need update params method, e.g.

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

also fields_for should plural (i think)...

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

Comments

Popular posts from this blog

c++ - CryptStringToBinary API behavior -

java.util.scanner - How to read and add only numbers to array from a text file -

iphone - Three second countdown in cocos2d -