【问题标题】:Provide another model's fields for nested form in Rails在 Rails 中为嵌套表单提供另一个模型的字段
【发布时间】:2015-09-20 03:19:17
【问题描述】:

我正在构建一个 Rails 应用程序来管理一个梦幻网球支架游戏。

这是我的模型。

玩家将提交他们的选择的游戏:

class Game < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
  has_many :picks, dependent: :destroy
  accepts_nested_attributes_for :picks

我匹配两个网球运动员的比赛:

class Match < ActiveRecord::Base
  belongs_to :event
  belongs_to :player_1, class_name: "Player"
  belongs_to :player_2, class_name: "Player"
  has_many :picks, dependent: :destroy

挑选模型。

class Pick < ActiveRecord::Base
  belongs_to :game
  belongs_to :match

我正在使用另一个表单中的嵌套表单。

<%= form_for(@game) do |f| %>
  <% if @game.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@game.errors.count, "error") %> prohibited this game from being saved:</h2>

      <ul>
      <% @game.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>


  <div class="field">
    <%= f.label :user_id %><br>
    <%= f.collection_select(:user_id, User.all, :id, :name) %>
  </div>
  <div class="field">
    <%= f.label :event_id %><br>
    <%= f.collection_select(:event_id, Event.all, :id, :title) %>
  </div>
  <div class="field">
    <%= f.label :score %><br>
    <%= f.number_field :score %>
  </div>
  <% @matches.each do |g| %>
  <%= f.fields_for :picks do |ff| %>
        <fieldset>
          <%= ff.label :match_id %>
          <%= ff.text_field :match_id %>
          <%= ff.label :winner, "Select the Winner" %> 
          <%= ff.text_field :winner %>
        </fieldset>
        <br>
  <% end %>
  <% end %>   
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

我想使用 Match 模型中的字段来填充 Pick 模型上的字段。例如,比赛有两名球员,我希望能够将球员的姓名拉入 :picks 表格,并且可能会在他们上使用 f.select。

我有一些关于 Match 模型的玩家数据,我想将其动态拉入 Pick 模型。无法弄清楚如何查询数据库并获取 Pick 嵌套表单要访问的字段属性。任何帮助,将不胜感激。

【问题讨论】:

    标签: ruby-on-rails forms nested-forms


    【解决方案1】:

    这就是我要做的。

    1. 摆脱“游戏”
    2. 制作“picks”模型来存储“游戏”信息

    我认为您目前遇到的主要问题是 GamePick 模型正在尝试做同样的事情。

    #app/models/match.rb
    class Match < ActiveRecord::Base
        # columns id | event_id | name | player_1 | player_2
        belongs_to :event
        has_many :picks
        belongs_to :player_1, class_name: "Player", primary_key: :player_1
        belongs_to :player_2, class_name: "Player", primary_key: :player_2
    
        def players
           [player_1, player_2]
        end
    end
    
    #app/models/pick.rb
    class Pick < ActiveRecord::Base
        # columns id | user_id | match | winner | etc
        belongs_to :user
        belongs_to :match, primary_key: :match
        has_one :winner, primary_key: :winner
    end
    

    这意味着您将能够执行以下操作:

    #app/views/picks/new.html.erb
    <% @matches.each do |match| %>
        <%= match.name %>
        <%= form_for match.picks.new do |f| %>
            <%= f.hidden_field :match, match.id %>
            <%= f.collection_select :winner, match.players, :id, :name, prompt: "Who will win?" %>
            <%= f.submit %>
        <% end %>
    <% end %>
    
    #app/controllers/picks_controller.rb
    class PicksController < ActionController::Base
       def new
           @matches = Match.all
       end
       def create
           @pick = Pick.new pick_params
           @pick.save
       end
    
       private
    
       def pick_params
           params.require(:pick).permit(:match, :winner).merge(user_id: current_user)
       end
    end
    

    这将使您能够以最简单和可扩展的方式“挑选”玩家。

    【讨论】:

    • 感谢您的回复。我在沙盒(一个新的 Rails 应用程序)中遵循了您的建议,但出现错误:未定义的方法 'pick'。我试图添加一个 @ 来匹配,并在匹配中替换。还有其他想法吗?我认为这是在正确的轨道上,您的帖子已经很有帮助。
    • 哪里出现错误,有没有给你文件和行参考?
    • 它确实给出了一个文件:app/views/picks/_form.html.erb:3:in `block in _app_views_picks__form_html_erb__3689731985020291361_70286657363160'
    • 参考链接是 433。这里是 431 - 436: else match = match_attribute_method?(method.to_s) match ? attribute_missing(match, *args, &block) : super end end
    • 还有最上面的错误是:NoMethodError in PicksController#new
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多