我正在编写一个简单的rails应用程序,我目前有2个模型,Location User,它们与Message模型具有相同的关系。也就是说,Location有很多消息,User有很多消息,Message属于User和Location。我目前正在尝试添加表单以在我的位置显示视图上创建新消息。这是一些代码:
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>
地点控制器:
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
我试图包含在location / show.html.erb
中的部分表格<%= form_for(@message) do |f| %>
<p>
<%= f.label "Leave a Message" %>
<%= f.text_area :content %>
</p>
<%= f.submit "submit" %>
<% end %>
当我尝试包含部分时,我得到以下错误
undefined method `model_name' for NilClass:Class
我假设表单正在尝试与位置控制器通信,因为它位于位置视图中,并且由于它无法在位置控制器中找到实例@message,因此它不知道该怎么做。我试图弄清楚如何在位置视图中的消息控制器中包含此表单。如果我为new_message_path创建一个视图,它工作正常,我猜,因为它在消息视图中运行,所以它引用回消息控制器。
我也想知道是否有任何方法可以创建一个链接到current_user和表单所在位置的消息(或者希望在我找出最后一个问题时。消息对象有一个location_id属性,如何使用我当前使用的页面(使用url / locations / location_id)将邮件链接到该位置?谢谢!
答案 0 :(得分:0)
首先,您需要在控制器中将@message
变量实际设置为新消息:
# locations_controller.rb
def show
@location = Location.find(params[:id])
@message = @location.messages.build(user_id: current_user.id)
end
使用@location.messages.build
会自动为location_id
添加@location.id
新邮件,我们也在这里设置user_id
。
有了这个,您应该能够在页面中构建表单(尽管您可能需要添加一些隐藏字段来存储user_id
和location_id
@message
)
完成后,您也可以减少messages_controller
。除非您希望有一个额外的页面来创建一个与某个位置无关的新消息,否则您可以摆脱new
动作(和路由)。然后,您可以将create
操作简化为:
# 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