4

I will setup the scenario followed by my question, in detail.

Here is the scenario:

I have a contact controller, with new and create actions. This is for a form I'd like users to fill out and to store their responses.

Contact controller:

class ContactController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(params[:contact])
    respond_to do |format|
      if @contact.save
        format.html { redirect_to social_path, notice: 'Message sent successfully!' }
      else
       format.html { render action: 'new' }
      end
    end
  end
end

I have a corresponding _form.html.erb partial, as well as a new.html.erb view, which im rendering the form partial, as you would do. These views are all located inside of the contact view folder, with corresponding routes.

_form.html.erb

<%= form_for @contact do |f| %>
  <% if @contact.errors.any? %>
    <h2>
      <%= pluralize(@contact.errors.count, "error") %> prohibited this contact from being saved:
    </h2>

    <ul>
    <% @contact.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  <% end %>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :name, :class => 'inline' %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :name, :placeholder => 'Kenny Powers' %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :subject %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :subject %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :email %>
  </div>
  <div class="large-10 columns">
    <%= f.text_field :email, :placeholder => 'kennypowers@example.com' %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns">
    <%= f.label :message %>
  </div>
  <div class="large-10 columns">
    <%= f.text_area :message %>
  </div>
</div>
<div class="row collapse">
  <div class="large-2 columns end">
    <%= f.submit %>
  </div>
</div>
<% end %>

new.html.erb <%= render 'contact/form' %>

I have created a static_pages controller, as I wanted to keep my mostly static pages separate from pages loading dynamic content.

Inside of the static_pages controller I have a social controller action which is empty. I'm displaying static content at social.html.erb, which is located in the static_pages view folder, with a match route as follows

match 'social' => 'static_pages#social'

social.html.erb

<%= render :template => 'contact/new', :@contact => Contact.new %>

static_pages_controller

def social

end

Cool, the social pages renders perfectly.

Now for the part im confused with:

How do I render the contact form in the social page? As it sits in the social.html.erb file I have

<%= render template: 'contact/new' %>

which gives me

ActionView::MissingTemplate in Static_pages#social

Showing app/views/contact/new.html.erb where line #1 raised:

1: <%= render 'form' %>

It is throwing a missing template error for the _form.html.erb in the contact/new.html.erb. If I try to specify the form location by adding

<%= render 'contact/form' %>

I get a undefined method model_name for NilClass:Class error.

Am I doing this completely wrong? Is there a better way to do what I am attempting? Can someone provide me with a layman explanation?

I know there are similar questions with rendering form partials into other controllers, but they are only one line solutions. I would greatly appreciate words to support WHY this is happening, or words to support a better/correct way of doing things.

If you need any more information/specific code, please let me know.

JamesDullaghan
  • 1,230
  • 11
  • 12
  • Maybe `_form.html.erb` is using a local variable or an instance variable that has not been initialized. Is there a line number in the last error message that could help ? – Baldrick May 11 '13 at 19:30
  • See this question: http://stackoverflow.com/questions/9304368/rails-3-render-partial-from-another-controller-error-actionviewmissingtempla - when rendering your form, you may have to pass in any objects used by that partial. – mccannf May 11 '13 at 19:36
  • can you add both the controller code and the _form code. Sounds like a easy problem to help with if we can see the code – fontno May 11 '13 at 19:38
  • Forms generally require a model object; without your form code or the controller code that preps for it, it's difficult to help. A warning flag is that you're trying to do something non-static in a "static" page, if your pathing is to be believed. – Dave Newton May 11 '13 at 19:39
  • line number 1, so it is an error with local variable or instance variable that has not been initialized. Let me read that posting, and try to pass in any object used by the partial. I have also added the git repository https://github.com/JamesDullaghan/Online-portfolio if you'd like to take a look. I didn't want to flood the question with such specifics. – JamesDullaghan May 11 '13 at 19:40
  • "Such specifics" are what make it an actual question. You asked to be informed what other information/specific code was needed, two people told you. Questions should be as self-contained as possible. – Dave Newton May 11 '13 at 19:43
  • Same comment as before: you're trying to render a form partial without a model object. Your social controller doesn't create the form model required by the partial. You're rendering a partial, not executing a controller, when you call `render`. – Dave Newton May 11 '13 at 19:53
  • I have added specific code Dave. I have also tried adding the object as you can see. No difference. Same `undefined method model_name` error – JamesDullaghan May 11 '13 at 19:54
  • Because that's not how you do it, IIRC; you could try `contact: Contact.new` and use `contact` in the partial (which will break your contracts controller) or create `@contact` in your social controller, etc. – Dave Newton May 11 '13 at 19:57
  • Okay, I see what you mean Dave. I added @contact = Contact.new in the social action of the static_pages controller, and passed that as the object to the form partial. I have a new error for the contacts_path, which is likely unrelated, but this problem seems solved. Really appreciate it Dave. How do I vote you up? – JamesDullaghan May 11 '13 at 20:00
  • 1
    @JamesDullaghan `contacts_path` requires a `contacts` routing in your routes.rb file. It's unclear if you just want to access contacts under a different name or if you're trying to keep contacts as an isolated resource but access it from multiple places. – Dave Newton May 11 '13 at 20:05
  • Dave, I was attempting to gain the knowledge to keep the contacts as an isolated resource, but access from multiple places, although for this specific example, I'm only using this resource once, so while the copy and paste answer makes sense, it's not the ideal answer to the question. I also apologize for not knowing the etiquette of stack overflow. – JamesDullaghan May 11 '13 at 20:18

1 Answers1

3

The solution is:

Copy and Paster your "social.html.erb" into your "/contact/new.html.erb"

then change that particular rendering to:

<%= render 'form' %>    # that's ok now, because you are in the right directory

now in the routes.rb:

resources :contacts     # it's important to add this for RESTful architecture

match 'social' => 'contact#new' # and DELETE the other line with => 'contact#index' because it is no more necessary

that was it.

UPDATE: here is my github-solution of your problem (in your application)

https://github.com/rubybrah/solution
swbergmann
  • 286
  • 1
  • 12
  • This is a comment, not an answer. – Dave Newton May 11 '13 at 19:37
  • i couldn't answer, and i want to help, what else could i do? – swbergmann May 11 '13 at 19:44
  • Either comment, or nothing. Answers are supposed to be answers; it's not a forum, it's Q&A. – Dave Newton May 11 '13 at 19:45
  • 3
    If the solution is "cut and paste" you're almost always solving the wrong problem. – Dave Newton May 11 '13 at 20:03
  • Much appreciated rubybrah, this is a cleaner solution than what I was attempting to do. – JamesDullaghan May 11 '13 at 20:07
  • the problem was, that @JamesDullaghan wanted to solve a RESTful problem in a static page. that did not work. If he sticks to RESTful programming (and uses the correct dynamic pages for his problems) he can solve his problem easily with the code from my updated answer above. – swbergmann May 11 '13 at 20:08
  • James, if my solution helped you fix your problem, it would be ok to rate it as the correct solution. cheers – swbergmann May 11 '13 at 20:13
  • It did help me solve the problem, but as Dave said, a copy paste solution doesn't help if I want to reuse this resource in multiple locations. I understand pasting the social page into the contact/new view and renaming the route will fix this, but how does this keep things DRY if I want to display that form elsewhere in the application? – JamesDullaghan May 11 '13 at 20:20