Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to create a nested child from parent object in ruby on rails 4
    primarykey
    data
    text
    <p>I try to reproduce in Rails 4 a functionality that was working fine in Rails 3: create a child record from the Show view of its parent using <code>new_parent_child_path(@parent)</code>.</p> <p>Unfortunately, when I validate the child creation, I get a message saying that the <code>child.parent_id field cannot be null</code>. Reading around, it looks that this new_parent_child_path(@parent) functionality is indeed hardly used. Here are parts of my code... </p> <p><strong>Models:</strong></p> <pre><code>class BusinessArea &lt; ActiveRecord::Base ... some checks ... validates :playground_id, presence: true belongs_to :playground belongs_to :owner, :class_name =&gt; "User", :foreign_key =&gt; "owner_id" # helps retrieving the owner name belongs_to :status, :class_name =&gt; "Parameter", :foreign_key =&gt; "status_id" # helps retrieving the status name has_many :business_flows end class BusinessFlow &lt; ActiveRecord::Base ... some checks ... validates :playground_id, presence: true belongs_to :playground belongs_to :owner, :class_name =&gt; "User", :foreign_key =&gt; "owner_id" # helps retrieving the owner name belongs_to :status, :class_name =&gt; "Parameter", :foreign_key =&gt; "status_id" # helps retrieving the status name has_many :business_processes belongs_to :business_area end </code></pre> <p><strong>Routes:</strong></p> <pre><code>ODQStep1::Application.routes.draw do #static pages get '/help', to: "static_pages#help" get '/about', to: "static_pages#about" get '/contact', to: "static_pages#contact" get '/home', to: "static_pages#home" #root definition root to: "static_pages#home" resources :sessions, only: [:new, :create, :destroy] get '/signin', to: 'sessions#new' , via: :get match '/signout', to: 'sessions#destroy', via: :delete resources :parameters resources :business_areas do resources :business_flows, :only=&gt;[:new, :create] end end </code></pre> <p><strong>Link to create child business flow is at the end of the Business Area Show view:</strong></p> <pre><code>&lt;% provide(:title, 'Managing business areas') %&gt; &lt;h1&gt;Business area: &lt;%= @business_area.name %&gt;&lt;/h1&gt; &lt;ul class="mid_menu"&gt; &lt;li&gt;&lt;%= link_to 'Edit', edit_business_area_path(@business_area) %&gt; |&lt;/li&gt; &lt;li&gt;&lt;%= link_to 'Back to list', business_areas_path %&gt; |&lt;/li&gt; &lt;li&gt;&lt;%= link_to 'Destroy', @business_area, confirm: 'Are you sure?', method: :delete %&gt;&lt;/li&gt; &lt;/ul&gt; &lt;!-- &lt;p id="notice"&gt;&lt;%= notice %&gt;&lt;/p&gt; --&gt; &lt;div class="tabbable"&gt; &lt;ul class="nav nav-tabs"&gt; &lt;li class="active"&gt;&lt;a href="#tab1" data-toggle="tab"&gt;Definition&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#tab2" data-toggle="tab"&gt;Ownership&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;div class="tab-content"&gt; &lt;div class="tab-pane active" id="tab1"&gt; &lt;!-- Tab content for Definition --&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Name: &lt;/div&gt; &lt;div class="span6"&gt;&lt;%= @business_area.name%&gt; &lt;/div&gt; &lt;div class="span1 text-right"&gt;Code: &lt;/div&gt; &lt;div class="span1"&gt;&lt;%= @business_area.code%&gt; &lt;/div&gt; &lt;div class="span1 text-right"&gt;Status: &lt;/div&gt; &lt;div class="span1"&gt;&lt;%= @business_area.status.name%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Description: &lt;/div&gt; &lt;div class="span10"&gt;&lt;%= @business_area.description%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Hierarchy: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.hierarchy%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;PCF index: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.PCF_index%&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;PCF reference: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.PCF_reference%&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Tab content --&gt; &lt;/div&gt; &lt;div class="tab-pane" id="tab2"&gt; &lt;!-- Tab content for Ownership --&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Unique id: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.id%&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;Created by: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.created_by%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Playground id: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.playground_id%&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;Created at: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.created_at%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Owner: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.owner.login%&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;Updated by: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.updated_by%&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt; &lt;/div&gt; &lt;div class="span2"&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;updated at: &lt;/div&gt; &lt;div class="span2"&gt;&lt;%= @business_area.updated_at%&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Tab content --&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;table width=100%&gt; &lt;tr&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr align="left"&gt; &lt;th&gt;Linked Business Flows&lt;/th&gt; &lt;th&gt;&lt;/th&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;table class="table table-striped table-condensed"&gt; &lt;%@business_area.business_flows.each do |business_flow| %&gt; &lt;tr align="left"&gt; &lt;td valign="top"&gt; &lt;%=link_to business_flow.code, business_flow%&gt; &lt;/td&gt; &lt;td valign="top"&gt; &lt;%=business_flow.name%&gt; &lt;/td&gt; &lt;td valign="top"&gt; &lt;%=business_flow.description%&gt; &lt;/td&gt; &lt;td&gt; &lt;/td&gt; &lt;/tr&gt; &lt;% end%&gt; &lt;/table&gt; &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &lt;%= link_to 'Add business flow', new_business_area_business_flow_path(@business_area) %&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; </code></pre> <p><strong>Business flow form</strong></p> <pre><code>&lt;%= form_for [@business_area, @business_flow] do |f| %&gt; &lt;% if @business_flow.errors.any? %&gt; &lt;div id="error_explanation"&gt; &lt;h2&gt;&lt;%= pluralize(@business_flow.errors.count, "error") %&gt; prohibited this business_flow from being saved:&lt;/h2&gt; &lt;ul&gt; &lt;% @business_flow.errors.full_messages.each do |msg| %&gt; &lt;li&gt;&lt;%= msg %&gt;&lt;/li&gt; &lt;% end %&gt; &lt;/ul&gt; &lt;/div&gt; &lt;% end %&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Name: &lt;/div&gt; &lt;div class="span10 field"&gt;&lt;%= f.text_field :name, :class =&gt; "span8" %&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Code: &lt;/div&gt; &lt;div class="span2 field"&gt;&lt;%= f.text_field :code %&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;Status: &lt;/div&gt; &lt;div class="span2 field"&gt;&lt;%= f.collection_select :status_id, @statuses_list, :id, :name %&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Description: &lt;/div&gt; &lt;div class="span10 field"&gt;&lt;%= f.text_area :description, :rows =&gt; 5, :class =&gt; "span8" %&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;Hierarchy: &lt;/div&gt; &lt;div class="span2 field"&gt;&lt;%= f.text_field :hierarchy %&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span2 text-right"&gt;PCF index: &lt;/div&gt; &lt;div class="span2 field"&gt;&lt;%= f.text_field :PCF_index %&gt; &lt;/div&gt; &lt;div class="span2 text-right"&gt;PCF reference: &lt;/div&gt; &lt;div class="span2 field"&gt;&lt;%= f.text_field :PCF_reference %&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="actions"&gt; &lt;%= f.submit %&gt; &lt;/div&gt; &lt;% end %&gt; </code></pre> <p><strong>Business Flows controller</strong></p> <pre><code>class BusinessFlowsController &lt; ApplicationController # Check for active session before_action :signed_in_user # Retrieve current business flow before_action :set_business_flow, only: [:show, :edit, :update, :destroy] # Create the list of statuses to be used in the form before_action :set_statuses_list, only: [:new, :edit, :update, :create] # GET /business_flows # GET /business_flows.json def index @business_flows = BusinessFlow.order("hierarchy ASC") respond_to do |format| format.html # index.html.erb format.json { render json: @business_flows } end end # GET /business_flows/1 # GET /business_flows/1.json def show ### Retrieved by Callback function end # GET /business_flows/new # GET /business_flows/new.json def new @business_flow = BusinessFlow.new @business_flow.business_area_id = params[:business_area_id] end # GET /business_flows/1/edit def edit ### Retrieved by Callback function end # POST /business_flows # POST /business_flows.json def create @business_flow = BusinessFlow.new(business_flow_params) @business_flow.business_area_id = params[:business_area_id] @business_flow.updated_by = current_user.login @business_flow.created_by = current_user.login @business_flow.playground_id = current_user.current_playground_id @business_flow.owner_id = current_user.id respond_to do |format| if @business_flow.save format.html { redirect_to @business_flow, notice: 'Business flow was successfully created.' } format.json { render json: @business_flow, status: :created, location: @business_flow } else format.html { render action: "new" } format.json { render json: @business_flow.errors, status: :unprocessable_entity } end end end # PUT /business_flows/1 # PUT /business_flows/1.json def update ### Retrieved by Callback function @business_flow.updated_by = current_user.login respond_to do |format| if @business_flow.update_attributes(business_flow_params) format.html { redirect_to @business_flow, notice: 'Business flow was successfully updated.' } format.json { head :no_content } else format.html { render action: "edit" } format.json { render json: @business_flow.errors, status: :unprocessable_entity } end end end # DELETE /business_flows/1 # DELETE /business_flows/1.json def destroy ### Retrieved by Callback function @business_flow.destroy respond_to do |format| format.html { redirect_to business_flows_url } format.json { head :no_content } end end ### private functions private ### Use callbacks to share common setup or constraints between actions. # Retrieve current business flow def set_business_flow @business_flow = BusinessFlow.includes(:owner, :status).find(params[:id]) end ### before filters # Check for active session def signed_in_user redirect_to signin_url, notice: "You must log in to access this page." unless signed_in? end ### strong parameters def business_flow_params params.require(:business_flow).permit(:code, :name, :hierarchy, :status_id, :PCF_index, :PCF_reference, :description) end end </code></pre> <p><strong>Log when clicking the New business flow link</strong></p> <pre><code>--- !ruby/hash:ActionController::Parameters action: new controller: business_flows business_area_id: '2' </code></pre> <p><strong>Log when validating business flow creation</strong></p> <pre><code>--- !ruby/hash:ActionController::Parameters utf8: ✓ authenticity_token: PwhUukDm3f0OIDhOZfeKxwgtH7M5GFoOuy63Mt7Tcw= business_flow: !ruby/hash:ActionController::Parameters name: aaaaaaa code: bbbbbbb status_id: '8' description: '' hierarchy: cccccccc PCF_index: '' PCF_reference: '' commit: Create Business flow action: create controller: business_flows </code></pre> <p>I could imagine hiding a <code>business_area_id</code> field in the form, but I hope for a smarter way to have the parameter passed to the new() function also available in the create() function even though they have to go through the strong parameters.</p> <p>Being a beginner, I can't say if my analysis of the problem is correct, and I hope you can help me finding a nice solution.</p> <p>Thanks a lot for your help,</p> <p>Best regards,</p> <p>Fred </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload