3

I'm using the 'refinerycms-inquiries' gem in my app to render an inquiry on my contact page.

The problem that I'm getting is that although I can use the <%= raw @page.content_for(:body) %> code on my other pages to render the content, I have no idea why I'm getting this in the inquiries#new view. Maybe someone can help me solve this more quicker, because I've looked for a couple of hours on the internet for an answer and looking through the source code.

This is the error:

 NoMethodError in Refinery/inquiries/inquiries#new 
undefined method `content_for' for nil:NilClass

Extracted source (around line #3):

1: <% content_for :body do %>
2:     <div>
3:       <%= raw @page.content_for(:body) %>
4:     </div>
5: <% end %>
6: 

I have to mention I'm a bit new to refinery and RoR.

This is my refinery/inquiries/inquiries/new.html.erb file:

<% content_for :body do %>
    <div class="contact">
      <%= raw @page.content_for(:body) %>
    </div>
<% end %>

<% content_for :body_content_left do %>
    <div class='inquiries'>
      <%= form_for [refinery, :inquiries, @inquiry] do |f| %>
          <%= render :partial => "/refinery/admin/error_messages",
                     :locals => {
                             :object => @inquiry,
                             :include_object_name => true
                     } %>
          <div class="field">
            <%= f.required_label :name, :class => 'placeholder-fallback' %>
            <%= f.text_field :name, :class => 'text', :required => 'required', :placeholder => t('name', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="field">
            <%= f.required_label :email, :class => 'placeholder-fallback' %>
            <%= f.email_field :email, :class => 'text email', :required => 'required', :placeholder => t('email', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="field">
            <%= f.label :phone, :class => 'placeholder-fallback' %>
            <%= f.text_field :phone, :class => 'text phone', :placeholder => t('phone', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class='field message_field'>
            <%= f.required_label :message, :class => 'placeholder-fallback' %>
            <%= f.text_area :message, :rows => 8, :required => 'required', :placeholder => t('message', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="actions">
            <%= f.submit t('.send') %>
          </div>
      <% end %>
    </div>
<% end %>
<%= render :partial => "/refinery/content_page" %>

This is my inquiries_controller.rb:

module Refinery
  module Inquiries
    class InquiriesController < ::ApplicationController

      before_filter :find_page, :only => [:create, :new]

      def thank_you
        @page = ::Refinery::Page.find_by_link_url("/contact/thank_you")
      end

      def new
        @inquiry = ::Refinery::Inquiries::Inquiry.new
      end

      def create
        @inquiry = ::Refinery::Inquiries::Inquiry.new(params[:inquiry])

        if @inquiry.save
          if @inquiry.ham?
            begin
              ::Refinery::Inquiries::InquiryMailer.notification(@inquiry, request).deliver
            rescue
              logger.warn "There was an error delivering an inquiry notification.\n#{$!}\n"
            end

            begin
              ::Refinery::Inquiries::InquiryMailer.confirmation(@inquiry, request).deliver
            rescue
              logger.warn "There was an error delivering an inquiry confirmation:\n#{$!}\n"
            end if ::Refinery::Inquiries::Setting.send_confirmation?
          end

          redirect_to refinery.thank_you_inquiries_inquiries_path
        else
          render :action => 'new'
        end
      end

      protected

      def find_page
        @page = ::Refinery::Page.find_by_link_url("/contact")
      end

    end
  end
end

And here is the config/routes.rb part that is generated by the 'refinerycms-inquiries' gem:

Refinery::Core::Engine.routes.draw do
    namespace :inquiries, :path => '' do
      get '/contact', :to => 'inquiries#new', :as => 'new_inquiry'

      resources :contact,
                :only => :create,
                :as => :inquiries,
                :controller => 'inquiries' do
        get :thank_you, :on => :collection
      end

      namespace :admin, :path => 'refinery' do
        resources :inquiries, :only => [:index, :show, :destroy] do
          get :spam, :on => :collection
          get :toggle_spam, :on => :member
        end

        scope :path => 'inquiries' do
          resources :settings, :only => [:edit, :update]
        end
      end
    end
  end
raulp
  • 196
  • 2
  • 15
  • This is an interesting question. I'm having similar issues as I'm trying to debug the Form generator that basically makes a custom Inquiry engine – CJBrew Oct 17 '14 at 15:02

2 Answers2

2

Looks like I've found the problem.

It turns out that ::Refinery::Page.find_by_url method from the inquiries_controller returned nil and I had to rewrite the find_page and thank_you methods like this:

  def thank_you
     @page = ::Refinery::Page.find_by_path("/contact/thank_you")
  end

  def find_page
     @page = ::Refinery::Page.find_by_path(/contact")
  end

in order for the :body and :side_body content to be rendered in my contact view. I've also noticed that by this modification and don't need to explicitly specify in my refinery/inquiries/inquiries/new.html.erb file to render the content_for(:body).

So the new view will look like the default one from the gem:

<% content_for :body_content_left do %>
    <div class='inquiries'>
      <%= form_for [refinery, :inquiries, @inquiry] do |f| %>
          <%= render :partial => "/refinery/admin/error_messages",
                     :locals => {
                             :object => @inquiry,
                             :include_object_name => true
                     } %>
          <div class="field">
            <%= f.required_label :name, :class => 'placeholder-fallback' %>
            <%= f.text_field :name, :class => 'text', :required => 'required', :placeholder => t('name', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="field">
            <%= f.required_label :email, :class => 'placeholder-fallback' %>
            <%= f.email_field :email, :class => 'text email', :required => 'required', :placeholder => t('email', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="field">
            <%= f.label :phone, :class => 'placeholder-fallback' %>
            <%= f.text_field :phone, :class => 'text phone', :placeholder => t('phone', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class='field message_field'>
            <%= f.required_label :message, :class => 'placeholder-fallback' %>
            <%= f.text_area :message, :rows => 8, :required => 'required', :placeholder => t('message', :scope => 'activerecord.attributes.refinery/inquiries/inquiry') %>
          </div>
          <div class="actions">
            <%= f.submit t('.send') %>
          </div>
      <% end %>
    </div>
<% end %>
<%= render :partial => "/refinery/content_page" %>

Hope this helps if anyone encounters the same problem.

raulp
  • 196
  • 2
  • 15
  • I guess you have made override on `_new` form , but can you share with us how did you reach to modify the controller of inquiries (assuming that any modifications to the controllers of Refinery are meant to be done by decorators) ? – R Milushev Dec 21 '12 at 18:59
  • Yes, you're right, I may have made a big mistake there because I have overwritten the controller in my refinery app and that's how it's working currently. After all, it's not the best solution, but it is a workaround (I'm still learning :-) ) – raulp Dec 21 '12 at 23:29
  • You're not wrong , you are brave . Go on and have a nice coding days. – R Milushev Dec 22 '12 at 09:41
0

The problem is missing definition for @page in your corresponding controler's actions (in your case 'new' and 'create'). I can see @inquiry instantiated . Try adding the statement

 @page = ::Refinery::Page.find_by_link_url("/contact")

both in you 'new' and 'create' actions of the InquriesController .

I am a bit curious , what version of Refinery you're using ? (strange how refinerycms-inquiries gem generates a content in routes.rb assuming that it is a mountable engine) .

R Milushev
  • 4,295
  • 3
  • 27
  • 35
  • There's actually a before_filter :find_page for the new and create action. It's right at the top written in the controller The refinery version I'm using is 2.0.8 – raulp Dec 20 '12 at 16:47
  • You are absolutely right , the variable @page is set . Let's try to debug it : cd to your project's dir and type `rails c` and then `::Refinery::Page.find_by_link_url("/contact")` .What is the output ? – R Milushev Dec 20 '12 at 18:49
  • I managed to solve the problem after all, but I can't post my answer sooner than 8 hours since I've posted my question because I don't have enough reputation. The problem is that in the db no page has a link_url, so I've used the find_by_path method which returns the refinery page that I requested. When I write that in the rails console it returns nil. I'll post the answer when I'm allowed too with all the modified code in the controller and view Sorry, I accidentally hit enter before I finished to write everything :) – raulp Dec 20 '12 at 18:58
  • 1
    You can post a summary on the comments too , the audience is curious :) – R Milushev Dec 20 '12 at 19:00