Rails 4:从另一个控制器的视图访问模型

时间:2016-02-01 21:27:12

标签: ruby-on-rails forms associations rails-activerecord

我对rails很新,我正在为一家商店写一个网站,我在这里有多个商店位置locations_controller,当人们填写表单时,我也有一个potentialClients_controller,请求使用他们的姓名,电子邮件等更多信息。

通过我的locations_controller我为每个位置提供了多个视图,并且在位置视图中,我想要包含一个访问potentialClients_controller的表单。

这是通过关系还是其他方式完成的?以下视图会引发First argument in form cannot contain nil or be empty错误,因为在此视图中,@potential_clientnil

如何使@potential_client可访问?

位置/ 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>

2 个答案:

答案 0 :(得分:1)

<强>假设:

  • 您的模型potential_client.rb有一个代码:

    class PotentialClient < ActiveRecord::Base
      belongs_to :location
      # ..
      # ..
    end
    
  • 您的模型location.rb有一个代码:

    class Location < ActiveRecord::Base
      has_many :potential_clients
      # ..
      # ..
    end
    

<强>解决方案:

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

位置/ 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>

推荐解决方案:

  • potentialClients_controller重命名为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
    
      # i.e.
      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>
    

更好的推荐解决方案:

  • 通过移除def newton中的def einsteinlocations_controller(等)来干扰您的方法。除了静态定义的这些方法之外,最好使用单个方法来删除重复的代码:即def new_potential_client,当然还有def create_potential_client个动作。在这些操作中,您通过传递location来确定newtoneinstein还是params[:id]。 I.E.您的网址可能类似于/locations/9876/new_potential_client

  • 与上面的一行相同,但您可能需要/locations/9876/new_potential_client而不是/locations/newton/new_potential_client。然后,你需要slu for。我使用的一个宝石是friendly_id

最佳推荐解决方案:

  • 使用具有RESTful实现的浅嵌套资源路由。更多信息HERE
  • 如果您使用浅层嵌套资源路由,您的网址将类似于/locations/9876/potential_clients/new
  • 或者,如果使用friendly_id slug名称,则网址将类似于/locations/newton/potential_clients/new

答案 1 :(得分:0)

杰里米,你试过这个吗? <%= form_for @potential_client do |f| %> 并在控制器动作集@potential_client = PotentialClient.new

可能会遗漏一些东西,但似乎是最直接的方法。

相关问题