Search code examples
ruby-on-railsrubynamespacesnested-attributes

Rails - how to reference namespaced table attributes in views


I am trying to learn how to use namespaces in my Rails 5 app.

I have an organisation model and I have also made a series of nested models under the folder name "stance". One of those models is called overview.

The associations are:

Organisation.rb

has_one :overview, class_name: Stance::Overview
    accepts_nested_attributes_for :overview,  reject_if: :all_blank, allow_destroy: true

Stance::Overview

class Stance::Overview < ApplicationRecord
    belongs_to :organisation, inverse_of: :overview

My controllers for stance resources are nested under a folder called stance.

My routes are:

namespace :stance do
    resources :overviews
    end

In my stance view partial, I am trying to render the attributes from the overview table.

I have tried:

<p><%= @overview.internal_explanation %></p>
<p><%= @stance_overview.internal_explanation %></p>
<p><%= @stance.overview.internal_explanation %></p>
<p><%= @stance::overview.internal_explanation %></p>

I want to display this partial in my organisation show. I am trying to do that with:

<%= render 'stance/overviews/internal', overview: @overview %>

But I can't figure out how to access the overview table. Do I need to add a reference to 'stance' in the associations?

I can see that in the console I need to write:

o = Stance::Overview.create(internal_explanation: "test") 
o = Stance::Overview.first

but I can't see how to use that in the code itself.

I can see in the console that there is a record for this attribute.

The name of the table in the schema is "stance_overview".

My organisation controller has:

class OrganisationsController < ApplicationController
  before_action :set_organisation, only: [:show, :edit, :update, :destroy]

    def index
    @organisations = Organisation.all

  end

  def show

  end

  def new
    @organisation = Organisation.new
    @organisation.build_overview

  end

  def edit
    @organisation.build_overview unless @organisation.overview
  end

  def create
    @organisation = Organisation.new(organisation_params)

    respond_to do |format|
      if @organisation.save
        format.html { redirect_to @organisation, notice: 'Organisation was successfully created.' }
        format.json { render :show, status: :created, location: @organisation }
      else
        format.html { render :new }
        format.json { render json: @organisation.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @organisation.update(organisation_params)
        format.html { redirect_to @organisation, notice: 'Organisation was successfully updated.' }
        format.json { render :show, status: :ok, location: @organisation }
      else
        format.html { render :edit }
        format.json { render json: @organisation.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @organisation.destroy
    respond_to do |format|
      format.html { redirect_to organisations_url, notice: 'Organisation was successfully destroyed.' }
      format.json { head :no_content }
    end
  end




private
    # Use callbacks to share common setup or constraints between actions.
    def set_organisation
      @organisation = Organisation.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def organisation_params
      params.fetch(:organisation, {}).permit(:title,  :comment,
        overview_attributes: [:internal_explanation, :external_explanation ]

        )
    end


end

I have also tried defining the strong params for organisation as:

 stance_overview_attributes: [:internal_explanation, :external_explanation ]

I keep getting an error that says:

undefined method `internal_explanation' for nil:NilClass

Can anyone refer me to materials to help me learn how to use namespaces in my app. I am trying to understand the fundamentals of this so that I can bank some knowledge. I am finding things through trial and error but not understanding what's actually required (although in this case, none of my attempts are working out).


Solution

  • To access Overview model(table) when you working not in Stance namespace you have to use Stance::Overview. If working for example in a controller that in Stance namespace you can use just Overview for access.

    To get access from the relation you don't need any additional notation just @organisation.overview.

    If I understand correctly in you case you have to declare your partial as

    <%= render 'stance/overviews/internal', overview: @organisation.overview %>

    and in the partial you have to use overview without @.