Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Show different nested fields depending on another associated model existing?

nested fields

  • Please log in to reply
1 reply to this topic

#1 klyrish

klyrish

    Signalman

  • Members
  • 10 posts
  • LocationDenver, CO

Posted 29 December 2013 - 09:14 PM

I'm building a site for my dynasty fantasy football league. For those not familiar with dynasty leagues, you draft players and have the option to then sign them to long-term contracts. Players have salary values and every GM has $130/year of cap space to build his team out.

 

We've been using a spreadsheet with around 20 tabs and it's just obnoxious. So I've been building the site and am finally tackling the complicated Players/Teams/Contracts relationships.

 

I had to build Contracts and Subcontracts because a Contract starts with a single team/player, but due to dropping players and trading, it's possible that one multi-year contract has more than one Team...so Contract uses a virtual attribute to set the initial team and create the Subcontracts by setting that team_id for each of the Subcontracts along with the rest of the information required.

 

What I'm trying to do now in players_controller#edit is to check and see if a Player has a contract and if so, build the associated Subcontracts fields and remove the new Contract fields. If there is no Contract, then the subcontract fields obviously wouldn't be built and the Contract fields would be. However, that's not happening. If a player has no Contract, it just shows the player fields. If a player has a Contract, then the associated Subcontracts fields appear as expected with the new Contract form gone.

 

In players_controller#edit, I have:

# GET /players/1/edit
  def edit
    @player = Player.find(params[:id])
    if @player.contract.nil?
      @player.build_contract
    else
      @player.contract.subcontracts.build
    end
   
  end

And in the _form partial, I have:

<% if @player.contract.nil? %>
    <%= f.fields_for :contract do |builder| %>
	  <%= render 'contract_fields', f: builder %>
    <% end %>	
<% else %>	
    <%= f.fields_for :subcontracts do |builder| %>
	<%= render 'subcontract_fields', f: builder %>
    <% end %>
<% end %>	

I've tried varying things by switching the logic with an unless statement and not having .nil? but nothing seems to work. When I remove the if/unless logic from the view, fields appear as expected, except that players who have a Contract now have the Subcontracts showing AND the new Contract fields. If I put an unless around just the Contract fields, they disappear from players with and without Contracts.

 

I just want the new Contract fields to appear if a player doesn't have a Contract yet and, if he does, only show the Subcontracts fields.

 

Any help would be appreciated!

 

 

Other relevant code below.

 

player.rb

class Player < ActiveRecord::Base
  attr_accessible :auction_value, :first_name, :last_name, :nfl_team, :position, :is_drafted, :is_bought_out, :is_extended, :is_franchised, :bye_week, :full_name, :contract_attributes, :subcontracts_attributes
  
  has_one :contract
  has_many :subcontracts, through: :contract
  
  default_scope order("auction_value desc")
  
  accepts_nested_attributes_for :contract,
    :reject_if => proc {|attributes|
      attributes.all? {|k,v| v.blank?}
    }
    
  accepts_nested_attributes_for :subcontracts,
    :reject_if => proc {|attributes|
      attributes.all? {|k,v| v.blank?}
  }

  ...
end 

contract.rb

class Contract < ActiveRecord::Base
  attr_accessible :contract_length, :is_bought_out, :bought_out_by_team_id, :is_extended, :is_franchised, :contract_start_year, :contracted_team, :player_id, :subcontracts_attributes
  attr_accessor :contracted_team
  
  belongs_to :player
  has_many :subcontracts
  has_many :teams, through: :subcontracts
  
  accepts_nested_attributes_for :subcontracts
  
  after_create :create_subcontracts


  def create_subcontracts
    contracted_team_id = self.contracted_team
    player = Player.find(self.player_id)
    salary = player.auction_value
    salary_progression = SalaryProgression.find(salary).attributes.to_a  

    contract_start_year = self.contract_start_year
    
    self.contract_length.times do |i|
      sub = Subcontract.new
      sub.contract_year = contract_start_year + i
      i += 1
      sub.salary_amount = salary_progression[i][1]
      sub.contract_id = self.id
      sub.team_id = contracted_team_id
      sub.save!
    end
     
  end
end

subcontract.rb

class Subcontract < ActiveRecord::Base
  attr_accessible :contract_id, :salary_amount, :team_id, :contract_year
  
  belongs_to :contract
  belongs_to :team
  
  has_one :player, through: :contract
  
end


#2 klyrish

klyrish

    Signalman

  • Members
  • 10 posts
  • LocationDenver, CO

Posted 29 December 2013 - 09:26 PM

I made the following update to the Player model and this seems to have fixed some weird issues where contracts were being partially nullified:

 

player.rb

accepts_nested_attributes_for :contract, :reject_if => lambda { |a| a[:contracted_team].blank? }   
accepts_nested_attributes_for :subcontracts, :reject_if => lambda { |a| a[:team_id].blank? }





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users