views:

504

answers:

3

I'm working on a Flex/Rails app. I've got a model with a has_many :through association that I'm trying to create. I've got it working with checkboxes on the plain rails pages, with the help of blogs like Paul Barry's has-many-through-checkboxes. Now I'm trying to get Flex to do the same and am having difficulty on how to send the equivalent checkbox parms in the Flex service call.

The model involved looks like this:

class PlayerAction < ActiveRecord::Base
  belongs_to :player
  belongs_to :action_type
  has_many :action_cards
  has_many :deck_cards, :through => :action_cards
end

The form on the rails page is this:

<% form_for PlayerAction.new do |f| %>
    <%= f.hidden_field  :player_id, {:value => @player.id} %>
    <%= f.collection_select(:action_type_id, ActionType.find(:all), :id, :desc) %>
    <ul>
        <% @player.hand.deck_cards.each do |deck_card| -%>
     <li><%= check_box_tag "player_action[deck_card_ids][]", deck_card.id -%><%= deck_card.title %>
      <% end -%>
     </ul>
    <%= f.submit 'Do Action' %>
<% end %>

This creates parameters which, in the rails log, looks like this:

Parameters: {"commit"=>"Do Action", "action"=>"create", "controller"=>"player_actions", "player_action"=>{"action_type_id"=>"1", "player_id"=>"9", "deck_card_ids"=>["87", "56"]}}

Using the TamperData plugin on Firefox, the parameters look like this:

player_action[player_id]=9
player_action[action_type_id]=1
player_action[deck_card_ids][]=87
player_action[deck_card_ids][]=56
commit=Do+Action

and finally, my Flex code for the service call is as follows. svcAction is an mx:HTTPService defined elsewhere. The routing and url works, I'm focusing on the params here :

svcAction.url = "/player_actions.xml";
var params:Object = new Object();
params['player_action[action_type_id]'] = 1;
params['player_action[player_id]'] = 8;
params['player_action[deck_cards_ids][]'] = 37;
params['player_action[deck_cards_ids][]'] = 19;
svcAction.send(params);

In the above code, the player_action[deck_cards_ids][] parms overwrite each other, so only one is sent, with the 2nd value. I've also tried arrays of the ids with

params['player_action[deck_cards_ids]'] = myIdsArray.toString();

and

params['player_action[deck_cards_ids]'] = "[" + myIdsArray.toString() + "]";

but neither of those worked either.

Any suggestions?

A: 

You issue may be in the view. Instead of passing back an array with elements like player_action[deck_card_ids][] = 87, it should be player_action[deck_card_ids][87] = true.

<ul>
  <% @player.hand.deck_cards.each do |deck_card| %>
    <li><%= check_box_tag "player_action[deck_card_ids][#{deck_card.id}]" %><%= deck_card.title %>
  <% end %>
</ul>
Sarah Mei
The view was working fine. The problem was with the Flex side. I think you mis-interpreted the TamperData output.
Ok. Good luck with it then, hopefully you get a better answer.
Sarah Mei
+1  A: 

I had copied the usage of the params Object in Flex from another service call that does an update (which I modeled after examples in the Flex on Rails book). Taking a fresh look at this, I realized this was a create, looked at another working create service, and ended up creating an xml request instead.

Here's the working Flex code snippet:

var request:XML =
  <player_action>
    <player_id>10</player_id>
    <action_type_id>1</action_type_id>
    <deck_card_ids>37</deck_card_ids>
    <deck_card_ids>103</deck_card_ids>
  </player_action>;
svcAction.request = request;
svcAction.send();

<mx:HTTPService id="svcAction" url="/player_actions.xml" contentType="application/xml" method="POST" resultFormat="e4x" result="handleActionResult(event)" />

At first I thought I needed the <deck_card_id> nested within a parent of <deck_card_ids>, but that didn't work. I actually use bound variables and curly brackets in there to use the values I want, but the above is the resulting xml.

A: 

It seems to me that your best bet would be to alter the Rails controller so as to parse different String keys in your params. That said, your existing controller might work. Try using params[ new String( "player_action[deck_cards_ids][]" ) ] = [ 37, 19 ];

jmreidy