Ruby on rails 3 Rails 3.2.2简单表单嵌套模型(有很多)可以工作,但需要改进

Ruby on rails 3 Rails 3.2.2简单表单嵌套模型(有很多)可以工作,但需要改进,ruby-on-rails-3,collections,nested-forms,simple-form,Ruby On Rails 3,Collections,Nested Forms,Simple Form,使用Rails 3.2.2中的simple_forms gem,我构建了一个表单来创建嵌套模型中的对象(railscasts.com上的Ryan Bates再次对此表示赞许),但我正在努力掌握一种多通关系的复杂性,而无需为我的游戏控制器的创建方法添加额外的代码 我正在使用accepts_nested_attributes_for:我的游戏模型中的参与者,希望能够批量分配2个必需的参与者对象 我有三门课:一场游戏,一个团队,和一个全桌参与者 参与者的存在使一支球队在比赛中可以被称为主队或客队 目前

使用Rails 3.2.2中的simple_forms gem,我构建了一个表单来创建嵌套模型中的对象(railscasts.com上的Ryan Bates再次对此表示赞许),但我正在努力掌握一种多通关系的复杂性,而无需为我的游戏控制器的创建方法添加额外的代码

我正在使用accepts_nested_attributes_for:我的游戏模型中的参与者,希望能够批量分配2个必需的参与者对象

我有三门课:一场游戏,一个团队,和一个全桌参与者

参与者的存在使一支球队在比赛中可以被称为主队或客队

目前,我正在使用表单中的select_标记创建两个psuedo参数,在保存新的@game对象后,我将在控制器中使用create方法创建参与者。我正在为主队和客队创建@game.participant。这一切都是可行的,但有点过于繁重,如果我想创建一个游戏锦标赛而不编写更多的控制器代码,则无法扩展

因此,现在我在新方法中构建了2.5倍的参与者,并尝试在不添加额外代码和删除create@games.participants的情况下让create和update正常工作

好的。。。问题是

  • builder.input:team_id,:collection=>team.all

    这会将对象id放在选择器中,我想要当前文件中生成的Team.full_名称 选择_标记“主页”,从_集合中为_选择选项(Team.all,:id,:full_name)和要添加的id 被推到团队id参数中。我正在努力寻找像样的简单表单和文档 查看gem源代码让我头疼(我没有能力解码它)

  • 我需要区分在新游戏对象中创建的两个参与者。这个 简单表格f。简单字段:参与者做,建设者不允许我做 :participants.first或:participants.last。我想创建一个隐藏字段设置:home\u团队 对于第一个参与者为true

  • 如果我能让这两个部分工作,那么我认为我的解决方案会起作用。如往常一样,我们非常感谢任何帮助或线索

    游戏模式:

    class Game < ActiveRecord::Base
      belongs_to :venue
      belongs_to :game_type
      has_and_belongs_to_many :tournaments
      has_many :participants, :dependent => :destroy
      has_many :teams, :through => :participants
    
      validates :kickoff, :venue_id, :presence => true
      accepts_nested_attributes_for :participants,
        :reject_if => lambda {|a| a[:game_id].blank? },
           :allow_destroy => :true
      def home_team
        self.teams.joins(:participants).where("participants.home_team = ?", true).first
      end
      def away_team
        self.teams.joins(:participants).where("participants.home_team = ?", false).first
      end
    end
    
        class Game < ActiveRecord::Base
          belongs_to :venue
          belongs_to :game_type
          has_and_belongs_to_many :tournaments
          has_many :participants, :dependent => :destroy
          has_many :teams, :through => :participants
    
          validates :kickoff, :venue_id, :presence => true
    
          accepts_nested_attributes_for :participants,
            :reject_if => lambda {|a| a[:team_id].blank? },
              :allow_destroy => :true
    
          def home_team
            self.teams.joins(:participants).where("participants.home_team = ?", true).first
          end
    
         def away_team
           self.teams.joins(:participants).where("participants.home_team = ?", false).first
         end
       end
    
    类游戏:销毁
    有许多:团队,:至=>:参与者
    验证:启动,:地点\ id,:状态=>true
    接受:参与者的\u嵌套\u属性\u,
    :reject_if=>lambda{a | a[:game_id].blank?},
    :allow_destroy=>:true
    def home_团队
    self.teams.joins(:参与者)。其中(“participants.home\u team=?”,true)。首先
    结束
    德福客队
    self.teams.joins(:参与者)。其中(“participants.home\u team=?”,false)。首先
    结束
    结束
    
    参与者模型:

    class Participant < ActiveRecord::Base
      belongs_to :game
      belongs_to :team
    end
    
    class参与者
    团队模式:

    class Team < ActiveRecord::Base
      has_many :participants, :dependent => :destroy
      has_many :games, :through => :participants
      validates :full_name, :presence => true
      validates :short_name, :presence => true, :length => { :within => 1..5 }
    end
    
    class团队:销毁
    有许多:游戏,:至=>:参与者
    验证:全名,:presence=>true
    验证:short_name,:presence=>true,:length=>{:within=>1..5}
    结束
    
    游戏控制器(新建和创建方法)

    class GamesControllerparams[:home],:home_team=>true)
    @game.participants.create(:team_id=>params[:away],:home_team=>false)
    format.html{重定向到游戏路径,注意:'游戏已成功创建。}
    其他的
    format.html{呈现操作:“新建”}
    结束
    结束
    结束
    
    游戏视图表单部分(实际上有另一部分,但为了便于阅读而包括在内)

    
    {:maxlength=>5,:size=>5}%>
    {:maxlength=>5,:size=>5}%>
    vention.all,提示:“选择场地”%>
    
    好的。。。如果有人感兴趣,我用以下方法解决了这两个问题:

  • 在类中使用了收集功能,而不是任何简单的表单帮助程序,因此游戏视图表单部分对收集行进行了以下更改:

    <%= builder.input :team_id, :collection => Team.all.collect{ |t| [t.full_name, t.id ]}%>
    
    Team.all.collect{| t |[t.full|u name,t.id]}%>
    
  • 我使用计数比较来设置veriable,并记录隐藏字段的值。这不是很好的目标代码,但意味着代码使用简单的表单帮助程序工作,控制器只使用.save(在create中)和update(在update中)属性,而不需要任何进一步的代码。很不错的。还稍微修改了accepts_nested_attributes_for,以查找空白的团队id,而不是游戏id(永远不会为空!)。现在代码如下所示

  • 游戏模式:

    class Game < ActiveRecord::Base
      belongs_to :venue
      belongs_to :game_type
      has_and_belongs_to_many :tournaments
      has_many :participants, :dependent => :destroy
      has_many :teams, :through => :participants
    
      validates :kickoff, :venue_id, :presence => true
      accepts_nested_attributes_for :participants,
        :reject_if => lambda {|a| a[:game_id].blank? },
           :allow_destroy => :true
      def home_team
        self.teams.joins(:participants).where("participants.home_team = ?", true).first
      end
      def away_team
        self.teams.joins(:participants).where("participants.home_team = ?", false).first
      end
    end
    
        class Game < ActiveRecord::Base
          belongs_to :venue
          belongs_to :game_type
          has_and_belongs_to_many :tournaments
          has_many :participants, :dependent => :destroy
          has_many :teams, :through => :participants
    
          validates :kickoff, :venue_id, :presence => true
    
          accepts_nested_attributes_for :participants,
            :reject_if => lambda {|a| a[:team_id].blank? },
              :allow_destroy => :true
    
          def home_team
            self.teams.joins(:participants).where("participants.home_team = ?", true).first
          end
    
         def away_team
           self.teams.joins(:participants).where("participants.home_team = ?", false).first
         end
       end
    
    类游戏:销毁
    有许多:团队,:至=>:参与者
    验证:启动,:地点\ id,:状态=>true
    接受:参与者的\u嵌套\u属性\u,
    :reject_if=>lambda{a | a[:team_id].blank?},
    :allow_destroy=>:true
    def home_团队
    self.teams.joins(:参与者)。其中(“participants.home\u team=?”,true)。首先
    结束
    德福客队
    self.teams.joins(:参与者)。其中(“participants.home\u team=?”,false)。首先
    结束
    结束
    
    游戏控制器(新建和创建方法)

    class GamesCon
    
        class GamesController < ApplicationController
          def new
            @game = Game.new
            2.times { @game.participants.build }
            respond_to do |format|
              format.html # new.html.erb
            end
          end
          def create
            @game = Game.new(params[:game])
            respond_to do |format|
              if @game.save
                format.html { redirect_to games_path, notice: 'Game was successfully created.' }
              else
                format.html { render action: "new" }
              end
            end
          end
        end
    
        <%= simple_form_for(@game) do |f| %>
          <%= f.error_notification %>
        <div class="form-inputs">
          <% count = 0 %>
          <%= f.simple_fields_for :participants do |builder| %>
            <% if count == 0 %>
              <% value = true %>
              <% count += 1 %>
            <% else %>
              <% value = false%>
            <% end %>
            <%= builder.input :home_team, :as => :hidden, :input_html => {:value => value} %>
            <%= builder.input :team_id, :collection => Team.all.collect{ |t| [t.full_name, t.id ]}%>
          <% end %>
          <%= f.input :home_goals, :input_html => {:maxlength => 5, :size => 5 }%>
          <%= f.input :away_goals, :input_html => {:maxlength => 5, :size => 5 }%>
          <%= f.input :kickoff %>
          <%= f.input :completed %>
          <%= f.input :game_type_id %>
          <%= f.input :venue_id ,:collection => Venue.all, prompt:  'Choose the venue'%>
        </div>
        <div class="form-actions">
           <%= f.button :submit %>
        </div>
      <% end %>