Reputation: 281
I am writing a simple rails app and I currently have 2 models, Location User, that have the same relationship to the Message model. That is, Location has many messages, User has many messages, and Message belongs to User and Location. I am currently trying to add a form to create a new message on my Location show view. Here is some code:
app/views/locations/show.html.erb:
<h1><%= @locaton.name %></h1>
<p><%= @location.location %></p>
<p><%= @location.discription %></p>
<%= link_to "Find a Different Location", crags_path %>
<h2> Messages
<ul>
<% @location.messages.each do |message|%>
</li>
<h3><%=message.user.username%></h3>
<p><%=message.content%></p>
</li>
<% end %>
</ul>
Locations Controller:
class LocationsController < ApplicationController
def index
@locations = Location.all
end
def show
@location = Location.find(params[:id])
end
def new
@Location = Location.new
end
def create
@location = Location.new(
name: params[:location][:name],
location: params[:location][:location],
discription: params[:location][:discription])
@location.save
flash.notice = "#{@location.name} Created!"
redirect_to location_path(@crag)
end
def edit
@location = Location.find(params[:id])
end
def update
@location = Location.find(params[:id])
@location.update_attributes(params[:location])
flash.notice = "#{@location.name} Updated!"
redirect_to crag_path(@location)
end
def destroy
@location = Location.find(params[:id])
@location.destroy
flash.notice = "#{@location.name} deleted."
redirect_to locations_path
end
end
MessagesController
class MessagesController < ApplicationController
def new
@message = Message.new
end
def create
@message = current_user.messages.build(
content: params[:message][:content])
redirect_to crags_path
end
end
Form partial that I am trying to include in location/show.html.erb
<%= form_for(@message) do |f| %>
<p>
<%= f.label "Leave a Message" %>
<%= f.text_area :content %>
</p>
<%= f.submit "submit" %>
<% end %>
When I try to include the partial i get the following error
undefined method `model_name' for NilClass:Class
and I assume that the form is trying to communicate with the locations controller since it is in a locations view, and since it cant find the instance @message in the locations controller, it doesn't know what to do. I am trying to figure out how to include this form from messages controller in the view for locations. If i create a view for new_message_path it works fine, again, I am guessing because it is functioning within the message views so it referes back to the messages controller.
I also was wondering if there was any way to creat a message that is linked to both current_user and to the location where the form is (or hopefully will be when I figure out the last problem. A message object has a location_id attribute, how do I use the page that I am currently on (with url /locations/location_id) to link the message to that location? Thanks!
Upvotes: 0
Views: 150
Reputation: 4344
Firstly, you'll need to actually set the @message
variable to a new message in the controller:
# locations_controller.rb
def show
@location = Location.find(params[:id])
@message = @location.messages.build(user_id: current_user.id)
end
Using @location.messages.build
will automatically populate the location_id
with @location.id
for the new message, and we're setting the user_id
here too.
With that in place, you should be able to build the form in your page (although you might need to add some hidden fields to store the user_id
and location_id
for @message
).
With that done, you can trim down your messages_controller
too. Unless you want to have an additional page to create a new message not tied to a location, you can probably get rid of your new
action (and route). Then you can simplify your create
action to:
# messages_controller.rb
def create
@message = Message.new(params[:message])
if @message.save
# whatever you want to do on successful save, for example:
flash[:success] = "Message created."
redirect_to location_path(@message.location_id)
else
# whatever you want to do if saving fails
end
end
Upvotes: 0