【问题标题】:Form for one model in view for another一个模型的表格,另一个模型的视图
【发布时间】:2013-04-18 13:29:21
【问题描述】:

我正在编写一个简单的 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

消息控制器

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)将消息链接到该位置?谢谢!

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    首先,您需要在控制器中将@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_idlocation_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
    

    【讨论】:

    • 感谢您的帮助!正是我想要的
    • 这些都没有经过测试,所以你可能会遇到一些减速带,但这应该会让你朝着正确的方向前进 :)
    • 还有一点不起作用的是 location_id 和 user_id 的隐藏字段没有显示在 params 哈希中,它们看起来都像 &lt;% f.hidden_field :user_id, :value =&gt; current_user.id%&gt;
    • 因为它们没有出现在参数上,所以当我创建消息时,我无法在消息控制器中分配它们,知道如何解决这个问题吗?
    • 它们应该已经设置在@message,所以您是否尝试过只使用&lt;% f.hidden_field :user_id %&gt;(和location_id)而不设置值?我会检查表单本身的 HTML,以确保那里的所有内容都设置正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多