Forum: Ruby on Rails I'm about to give up...I guess noone can help with passing a

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0c51049fb747cd60088e4878458e05d1?d=identicon&s=25 Rick Schumeyer (Guest)
on 2007-02-16 19:24
(Received via mailing list)
No one seems to be able to help with my request.  I bet this can be done
in rails, but I'm not going to figure it out without any help anytime
soon.

Trying to be brief:  I have three classes: Account, Employee, and
AccountEmployeeRelation (which contains more than just the FKs).
In the form where I create a new account, I know how to add a ONE linked
employee.  I do not know how to extend this to add MULTIPLE linked
employees.
Here is the working code for one employee:

  def new
    @account = Account.new
    @relation = AccountEmployeeRelation.new
  end

  def create
    @account = Account.new(params[:account])
    @relation = AccountEmployeeRelation.new(params[:relation])
    @account.account_employee_relations << @relation
    @account.save
    @relation.save
    redirect_to :action => :list
  end

The View:
<% form_for :account, :url => { :action => :create } do |form| %>
Title: <%= form.text_field :title %><br/>

<% fields_for :relation do |f|%>
   Employee: <%= f.select (:employee_id, Employee.find(:all).map{|u|
[u.name, u.id]}) %><br/>
<% end %>

<%= submit_tag %>
<% end %>

Can anyone help with extending this?  I think new needs to look like:
  def new
    @relations = []
    3.times do # I would not really do it this way.
      @relations << AccountEmployeeRelation.new
    end
  end

But I'm stuck on the view.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-02-16 19:41
(Received via mailing list)
Rick Schumeyer wrote:

>   def new
>     @account = Account.new
>     @relation = AccountEmployeeRelation.new

I will suggest something really sucky. Either it will work
brilliantly, or you will get your answer from others leaping to your
defense from me.

     3.times do |idx|
       instance_eval "@relations_#{idx} = AccountEmployeeRelation.new"
     end
 ...

>     @account = Account.new(params[:account])

     3.times do |idx|
        relation =
AccountEmployeeRelation.new(params[:"relation_#{idx}"])
        account.account_employee_relations << relation
     end
...

> The View:
> <% form_for :account, :url => { :action => :create } do |form| %>
> Title: <%= form.text_field :title %><br/>

     3.times do |idx|  #  similar symbol-abuse here...

 <% fields_for :"relation_#{}" do |f|%>
>    Employee: <%= f.select (:employee_id, Employee.find(:all).map{|u|
> [u.name, u.id]}) %><br/>
> <% end %>

And so on. However, I suspect in general you user interface is
too-closely matching the exact shape of your database. It should match
the way your users will typically enter their data.

--
  Phlip
  http://c2.com/cgi/wiki?ZeekLand  <-- NOT a blog!!
361ba1bcc1d2c5a8885dd093dbb96bb6?d=identicon&s=25 Michael Kovacs (Guest)
on 2007-02-16 19:58
(Received via mailing list)
Rick,

You can set multiple values on a collection like this:

@account.account_employee_ids = params[:relation_ids]

where params[:relation_ids] is an array of the relationship ids.

I wrote up an example in my blog awhile back:

http://javathehutt.blogspot.com/2006/08/rails-real...
relation.html

Also if you need to initialize a relationship when you create a new
instance see this post from hasmanyjosh:

http://blog.hasmanythrough.com/2007/1/22/using-fau...
initialize-values

Hope that helps,

-Michael
http://javathehutt.blogspot.com
0c51049fb747cd60088e4878458e05d1?d=identicon&s=25 Rick (Guest)
on 2007-02-16 20:00
(Received via mailing list)
Thanks, I will try your suggestions shortly.

I'm open to suggestons about my interface.  If I wanted to make the
inerface easy (for me) I would make the user create an Account, and
then later go back and add assigned Employees.  I think it will be
more convenient (but not for me) to be able to assign employees on the
same form that creates the account.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2007-02-16 20:02
(Received via mailing list)
Rick wrote:

> Thanks, I will try your suggestions shortly.

Try Mike's sooner. ;-)

> I'm open to suggestons about my interface.  If I wanted to make the
> inerface easy (for me) I would make the user create an Account, and
> then later go back and add assigned Employees.  I think it will be
> more convenient (but not for me) to be able to assign employees on the
> same form that creates the account.

The best deal there is show them a working interface as soon as
possible, with a few important features in it. Then they can request a
better look-and-feel, based on experience with the prototype...

--
  Phlip
  http://c2.com/cgi/wiki?ZeekLand  <-- NOT a blog!!
0c51049fb747cd60088e4878458e05d1?d=identicon&s=25 Rick (Guest)
on 2007-02-16 21:16
(Received via mailing list)
I'm quite lost.

I tried the suggestions at the first link...the check_box_tag, which
comes from your page, seems to work.

<% @account.account_employee_relations.each do |child| %>
<%=check_box_tag 'account[account_employee_relation_ids][]', child.id,
true %> <br/>
<%end%>

This produces (for each check box):

<input checked="checked" id="account[account_employee_relation_ids][]"
name="account[account_employee_relation_ids][]" type="checkbox" />

But when I change the check box to a text field:

<%= text_field 'account[account_employee_relation_ids][]', child.id
%>

I get an error:

`@account[account_employee_relation_ids]' is not allowed as an
instance variable name
Aaf9d67916c3c07e43a20e5e885f757b?d=identicon&s=25 Asa Hopkins (asa)
on 2007-02-17 02:28
Rick,

I did something this with a bit of AJAX.  Basically, I gave the user the
option to tell me how many fields they wanted, and then had the form
load a partial with teh right number of fields.

Here's the relevant bit of the _form.rhtml partial:

p><label for="custom_field_select_options">Select
options</label><br/></p>
number of options: <%= text_field 'select_field', 'options_number',
:id=>"watch_this", :value=>@num%>
<div id="select_fields">
  <%= render :partial=>"select_fields", :locals=>{:num=>@num}%>
</div>
<%= observe_field "watch_this", :url=>{:action=>"select_fields",
:controller=>"custom_fields",:params=>{:campaign_id=>@campaign.id,
:id=>@custom_field.id}}, :update=>"select_fields", :with=>"num" %>

And the _select_fields partial:

<% if num.nil?
  num = @num
end
%>
<% if num.nil? or num == 0
  num=3
end%>
  enter "select" options:<br />
  <% num.times do |i|
    if !@custom_field.nil? and @custom_field.field_type=="Select"
      value = @custom_field.select_options[i]
    else
      value = ""
    end  -%>
  <%=(i+1).to_s%>) <%= text_field 'select_field', 'options',:index=>i,
:value=>value %><br />
  <% end -%>


The select_fields action just collects and passes through the number of
fields requested:

  def select_fields
    unless params[:id].nil?
      @custom_field = CustomField.find(params[:id])
    end
    @num = params[:num].to_i
    render :partial=>'select_fields', :protocol=>@@protocol
  end

Hope that's helpful.  You could do it with just an RJS response to a
form_remote_tag instead of watching the field if you want.

In the end the (variable number of) params come in as a nested hash,
which I then pull apart and assign appropriately.

Asa
This topic is locked and can not be replied to.