【问题标题】:Auto-fill parent and grandparent ids in grandchild form_for在孙子 form_for 中自动填充父母和祖父母 ID
【发布时间】:2013-06-29 01:48:14
【问题描述】:

我有三个脚手架:国家、州和地区。

我的路线:

NetworkManager::Application.routes.draw do
    root to: "countries#index"
    resources :countries
    resources :states
    resources :districts    
end

我从国家到州。当我从各州回来时,我希望它带我回到母国。与州 地区相同。

我知道如何使用country_path(@state.country_id) 从州插入国家/地区链接 我在自动将正确的国家和州自动插入州和地区 form_for 时遇到问题。我不希望用户每次都必须选择国家和州,因为他们从 Country 视图创建了一个新州,并从 State 视图创建了一个新区。

那么,如何将 Country 和 State id 传递给 form_for?

【问题讨论】:

    标签: ruby-on-rails nested form-for


    【解决方案1】:

    假设您的路线设置正确:

    resources :countries do
      resources :states
    end
    
    resources :states do
      resources :districts
    end
    

    (我知道它们来自您之前的问题)

    form_for [@country, @state]
    

    转换为 country_and_state_path(@country, @state)。

    数组取决于您的嵌套。如果您按照推荐的方式进行两个深度学习,则可以保持该模式继续下去:

    form_for [@state, @district]
    

    等等。如果没有,那么类似:

    form_for [@country, @state, @district]
    

    也可以。所以,这就是那里的模式——取决于你的路线。

    希望有帮助!

    【讨论】:

    • 我实际上决定不为这些嵌套使用任何嵌套,而是为每个路径使用单独的路径,然后设置它们之间的链接。更多信息在单独的答案中。也许你可以给我一个更好的建议。
    【解决方案2】:

    目前我已经解决了这个问题。虽然不是我喜欢的方式:

    我将通过描述我如何将一个地区添加到一个州来解释这一点,因为那是更复杂的一个。

    State - show.html.erb(仅限新路径代码)将 GET 参数设置为 state 的 id 和 country_id,最好我想以其他方式发送它们,但我需要同时发送它们。

    <td colspan=4>
        <%= 
        link_to 'New District', 
        new_district_path(
            :country_id => @state.country_id, 
            :state_id => @state.id
        )
        %>
    </td>
    

    District - new.html.erb(将 country_id 和 state_id 设置为实例值或传递的参数...我想使用 POST 来发送这些参数)

    <h1>New district</h1>
    
    <%
    @district.country_id = @district.country_id || params[:country_id] || ""
    @district.state_id = @district.state_id || params[:state_id] || ""
    %>
    
    <%= render 'form' %>
    
    <%= link_to 'Back', state_path(params[:state_id]) %>
    

    区 - _form.html.erb

    <%= form_for(@district) do |f| %>
      <% if @district.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@district.errors.count, "error") %> prohibited this district from being saved:</h2>
    
          <ul>
          <% @district.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
          <% end %>
          </ul>
        </div>
      <% end %>
    
      <div class="field">
        <%= f.label :name %><br>
        <%= f.text_field :name %>
      </div>
      <div class="field">
        <%= f.label :country_id %><br>
        <%= f.number_field :country_id %>
      </div>
      <div class="field">
        <%= f.label :state_id %><br>
        <%= f.number_field :state_id %>
      </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>
    

    【讨论】:

    • 一个国家不属于一个国家吗?如果是这样,那么该地区不需要直接知道它属于哪个国家,它只需要知道状态即可。它可以通过州(district.state.country)来确定国家。我知道您可能希望页面上的表单控件允许用户更改其状态,但状态应该为您提供足够的信息来完成所有操作。所以,也许那里有简化事情的空间。另外,一个地区可以存在一个零状态吗?如果没有,那么你真的不需要通过州,因为任何现有的地区都会有一个州。
    • 我试图解决的问题是,当用户创建新区时,状态字段不会自动填充,因为我无法提取州 ID。我想我可以让每一个都成为前一个的子路径,只处理父子关系。我在这个国家唯一需要的地方是表格,因为我要求它。但我不一定需要它。我实际上是在让每个孩子都认识每个祖先的地方。也许我应该把它换成亲子。如果我这样做,使用嵌套路由是否比通过变量传递我的状态更好?
    • 如果您看起来高于两个级别(即为一个地区查找国家/地区),您最终需要传递变量。在这方面它不是相互排斥的。层次结构为您做的唯一一件事是在创建新实体时提供帮助,因为它假定您将在父级的上下文中创建一个新实体(即从现有状态页面创建一个新区)。但是对于显示/编辑,您不需要层次结构。
    • 这是一种在不使用 GET 参数(例如 ?country_id=1)的情况下传递父变量的方法,而不是使用两级层次结构
    • 不适用于创建新实体。但是,一旦实体存在,您就可以通过模型本身访问关联(因为它们将被创建并保存)。但是要制作新的,您需要以某种方式知道应该关联什么。当然,如果您希望用户在新页面本身上选择该信息,那也是一种选择。但除此之外,这些几乎都是您的选择 AFAIK。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2015-08-30
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多