Nathan Guo
Nathan Guo

Reputation: 75

Rails 3: Modifying RESTful Controller 'Create' Logic

I'm trying to modify the logic within a RESTful controller. In the current implementation, I have the following:

members_controller.rb

def create
    @team = current_team
    player = Player.find(params[:player_id])
    @member = @team.add_player(player.id)

    respond_to do |format|
      if @member.save
            format.html { redirect_to(@team, :notice => 'Member was successfully added.') }
            format.js { @current_member = @member }
            format.xml  { render :xml => @member, 
            :status => :created, :location => @member } 
      else
            format.html { redirect_to(@team, :notice => 'Member already exists.') }
            format.xml  { render :xml => @member.errors, 
            :status => :unprocessable_entity }
      end
    end
  end

team.rb

has_many :members, :dependent => :destroy

def add_player(player_id)
    current_member = members.find_by_player_id(player_id)
    if current_member
        # will not add duplicate member
    else
        current_member = members.build(:player_id => player_id)
    end
    current_member
end

This is lacking some functionality as I want to be able to control whether the member is saved by checking other attributes of the member against the player. In the current implementation, if I try to add a member that already exists, it is still getting redirected to @team with the notice 'Member was successfully added.', even though no member is being added. If I try to remove the redundancy by having the following, the controller adds duplicate members.

@team = current_team
@member = @team.add_player(:player_id)

Why is my current logic allowing me to not save a duplicate member, but still responding to the @member.save route? How do I control it properly?

Upvotes: 0

Views: 336

Answers (2)

glarkou
glarkou

Reputation: 7101

Instead of

def add_player(player_id)
current_member = members.find_by_player_id(player_id)
if current_member
    # will not add duplicate member
else
    current_member = members.build(:player_id => player_id)
end
current_member
end

Try:

Member.rb

validates_uniqueness_of :player_id, :scope => :team_id

team.rb

def add_player(player_id)
    current_member = members.build(:player_id => player_id)   
    current_member
end

Upvotes: 1

Jimmy Baker
Jimmy Baker

Reputation: 3255

ntenisOT is correct. When you're calling build inside team.rb, you're not actually saving the membership, you're only adding the player to the team on that particular team object. Also, the controller is still responding to save because you're calling save on the player which returns true.

Upvotes: 0

Related Questions