Note that there are some explanatory texts on larger screens.

plurals
  1. PORails 3.2.2 Simple Form Nested Model (has_many through) works but want to improve
    primarykey
    data
    text
    <p>Using the simple_forms gem in Rails 3.2.2, I have built a form to create objects in a nested model (kudos again to Ryan Bates over at railscasts.com) but I am struggling to master the complexity of a has_many through relationship without adding extra code to the create method of my Games controller.</p> <p>I am using accepts_nested_attributes_for :participants in my Game model with the hope of being able to mass assign the 2 required participant objects.</p> <p>I have three classes: a Game, a Team, and a through table Participant</p> <p>Participant exists so a team can be noted as the home or away team in a game.</p> <p>Currently, I am using the select_tag in the form to create a couple of psuedo params that I then use to create the participants in the create method in the controller after I have saved the new @game object I am creating a @game.participant for the home team and the away team. This all works but is a bit too heavy lifting and can't be extended if I wanted, for example, to create a tournament of games without writing more controller code.</p> <p>So now I build 2.times participants in the new method and am trying to get create and update to work without adding extra code and removing the creating @games.participants in the create method.</p> <p>Ok ... the problems... </p> <ol> <li><p>builder.input :team_id, :collection => Team.all</p> <p>This puts the object id in the selector, I want the Team.full_name as is produced in the current select_tag "home", options_from_collection_for_select(Team.all, :id, :full_name) and the id to be pushed into the team_id param. I am struggling to find decent simple_forms documentation and looking through the gem source has given me a headache (I'm not good enough to decode it)</p></li> <li><p>I need to differentiate between the two participants created in the new Game object. The simple_form f.simple_fields_for :participants do |builder| won't allow me to do :participants.first or :participants.last. I want to create a hidden field setting the :home_team to true for the first participant.</p></li> </ol> <p>If I can get these two pieces working then I think my solution would work. Any help or clues are, as always, hugely appreciated.</p> <p>Game Model:</p> <pre><code>class Game &lt; ActiveRecord::Base belongs_to :venue belongs_to :game_type has_and_belongs_to_many :tournaments has_many :participants, :dependent =&gt; :destroy has_many :teams, :through =&gt; :participants validates :kickoff, :venue_id, :presence =&gt; true accepts_nested_attributes_for :participants, :reject_if =&gt; lambda {|a| a[:game_id].blank? }, :allow_destroy =&gt; :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 </code></pre> <p>Participant Model:</p> <pre><code>class Participant &lt; ActiveRecord::Base belongs_to :game belongs_to :team end </code></pre> <p>Team Model:</p> <pre><code>class Team &lt; ActiveRecord::Base has_many :participants, :dependent =&gt; :destroy has_many :games, :through =&gt; :participants validates :full_name, :presence =&gt; true validates :short_name, :presence =&gt; true, :length =&gt; { :within =&gt; 1..5 } end </code></pre> <p>Games Controller (New and Create Methods)</p> <pre><code>class GamesController &lt; ApplicationController def new @game = Game.new ### This section is not currently implemented # 2.times { @game.participants.build } ### End of unimplemented section 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 @game.participants.create(:team_id =&gt; params[:home], :home_team =&gt; true) @game.participants.create(:team_id =&gt; params[:away], :home_team =&gt; false) format.html { redirect_to games_path, notice: 'Game was successfully created.' } else format.html { render action: "new" } end end end </code></pre> <p>Games View Form Partial (actually has another partial but included for ease of reading)</p> <pre><code>&lt;%= simple_form_for(@game) do |f| %&gt; &lt;%= f.error_notification %&gt; &lt;div class="form-inputs"&gt; &lt;%= label_tag "home", "Home Team"%&gt; &lt;%= select_tag "home", options_from_collection_for_select(Team.all, :id, :full_name)%&gt; &lt;!-- This section is not working properly --&gt; &lt;!-- &lt;%=# f.simple_fields_for :participants do |builder| %&gt; --&gt; &lt;!-- &lt;%=# builder.input :team_id, :collection =&gt; Team.all, :selected =&gt; :full_name %&gt; --&gt; &lt;!-- &lt;%# end %&gt; --&gt; &lt;!-- End of not working properly section --&gt; &lt;%= f.input :home_goals, :input_html =&gt; {:maxlength =&gt; 5, :size =&gt; 5 }%&gt; &lt;%= f.input :away_goals, :input_html =&gt; {:maxlength =&gt; 5, :size =&gt; 5 }%&gt; &lt;%= select_tag "away", options_from_collection_for_select(Team.all, :id, :full_name)%&gt; &lt;%= label_tag "away", "Away Team"%&gt; &lt;%= f.input :kickoff %&gt; &lt;%= f.input :completed %&gt; &lt;%= f.input :game_type_id %&gt; &lt;%= f.input :venue_id ,:collection =&gt; Venue.all, prompt: 'Choose the venue'%&gt; &lt;/div&gt; &lt;div class="form-actions"&gt; &lt;%= f.button :submit %&gt; &lt;/div&gt; &lt;% end %&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload