I am relatively new to rails and am writing a website for a store where I have a locations_controller
for the multiple store locations and I also have a potentialClients_controller
for when people fill out a form, requesting more information using their name, email, etc.
Through my locations_controller
I have several views for each location, and in the location's view, I want to include a form that accesses the potentialClients_controller
.
Is this done through relationships or some other way? The view below throws First argument in form cannot contain nil or be empty
error because in this view, @potential_client
is nil
.
How do I make @potential_client
accessible?
locations/Newton.html.erb
<div class="main-content">
<h1>Newton, MA</h1>
<div class="wrapper">
<div class="form-container">
<%= form_for @potential_client do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br />
<%= f.label :email %>
<%= f.email_field :email %><br />
<%= f.label :phone %>
<%= f.number_field :phone %><br />
<%= f.label :message %>
<%= f.text_field :message %><br />
<%= f.submit "Submit" %>
<% end %>
</div>
</div>
</div>
Assumptions:
You have a model potential_client.rb
having a code:
class PotentialClient < ActiveRecord::Base belongs_to :location # .. # .. end
You have a model location.rb
having a code:
class Location < ActiveRecord::Base has_many :potential_clients # .. # .. end
Solution:
locations_controller.rb
class LocationsController < ApplicationController
def newton
@location = Location.find(1) # if your location with id=1 is newton
# or if you are using an attribute to identify the location, i.e. name, then uncomment the following instead, and remove the line above
# @location = Location.find_by(name: 'newton')
end
end
locations/newton.html.erb
<div class="main-content">
<h1>Newton, MA</h1>
<div class="wrapper">
<div class="form-container">
<%= form_for @location.potential_clients.build do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br />
<%= f.label :email %>
<%= f.email_field :email %><br />
<%= f.label :phone %>
<%= f.number_field :phone %><br />
<%= f.label :message %>
<%= f.text_field :message %><br />
<%= f.submit "Submit" %>
<% end %>
</div>
</div>
</div>
Recommended Solution:
potentialClients_controller
to potential_clients_controller
locations_controller.rb
LocationsController < ApplicationController def newton @location = Location.find(1) # if your location with id=1 is newton @potential_client = @location.potential_clients.build end # ie def einstein @location = Location.find(2) # if your location with id=2 is einstein @potential_client = @location.potential_clients.build end # .. # .. end
locations/newton.html.erb
<div class="main-content"> <h1>Newton, MA</h1> <div class="wrapper"> <div class="form-container"> <%= form_for @potential_client do |f| %> <%= f.label :name %> <%= f.text_field :name %><br /> <%= f.label :email %> <%= f.email_field :email %><br /> <%= f.label :phone %> <%= f.number_field :phone %><br /> <%= f.label :message %> <%= f.text_field :message %><br /> <%= f.submit "Submit" %> <% end %> </div> </div> </div>
Better Recommended Solution:
DRY up you methods by removing def newton
and def einstein
(etc) in your locations_controller
. Instead of these methods that are statically defined, it is better to use a single method to remove duplicate code: ie def new_potential_client
and also of course the def create_potential_client
actions. In these actions, you identify if the location
is newton
or einstein
by passing the params[:id]
. IE your url might be something like /locations/9876/new_potential_client
Same as the line just above, but instead of /locations/9876/new_potential_client
, you might want /locations/newton/new_potential_client
instead. Then, you would need slugs for this. One gem I use is friendly_id
Best Recommended Solution:
/locations/9876/potential_clients/new
friendly_id
slug names, url will look like /locations/newton/potential_clients/new
Jeremy, have you tried this? <%= form_for @potential_client do |f| %>
<%= form_for @potential_client do |f| %>
and in the controller action set @potential_client = PotentialClient.new
Might be missing something but seems to be the most straightforward way to do this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.