views:

351

answers:

2

I need to have a view able to update an array attribute on a model such that I can dynamically add things on the view to be able to add this. Does that even make sense?

Basically a Foo has urls. So in the DB I just have a text datatype that I want to store the comma separated list of urls, and I override the default AR setter and getter so I can assign an array, and get an array for the values and it takes care of the joining and splitting.

What I'm lost at is how best to do the view. I need one text field initially, but then a 'add another url' link to tack on another text field for another url, and another, etc, etc.

Is there a 'rails way' to do this, or do I have to roll my own?

+1  A: 

Basically, what you want to eventually happen is @foo.urls = params[:urls] where params[:urls] is an array, and the #urls= setter is smart enough to handle an array, yes?

I can't speak from personal experience on this exact case, but here's what I would try…

First of all, make use of serialize on your model. For example, serialize :urls, Array – it sounds like you've already got a working getter and setter, but it's always nice to reuse what ActiveRecord provides.

Next, in your views, it all depends on how you're naming your text fields. Rails will parse parameters into array if they are named according to convention. To follow this convention, your text field names need to resemble something like foo[urls][]. You might simply use text_field_tag "foo[urls][]", or f.text_field_tag "urls[]" (though I can't recall off the top of my head whether the latter is valid – give it a try).

When your text field tags are named appropriately, then the rest should follow nicely from there. You'll have an array in params[:foo][:urls] and passing params into a call to Foo.new or Foo.create or @foo.update_attributes will do the right thing.

(Forgive any lapses in syntax above, this is all off the top of my head.)

Nick Zadrozny
+3  A: 

For the dynamic addition of form fields there really isn't a specific "Rails way" to do it. Rolling your own Javascript using jQuery or Prototype is not that difficult.

In your view:

<div id="url_list">
  <%= render :partial => "url_form", :collection => @my.urls %>
</div>

<%= button_to_function 'Add' { |page| page.insert_html :bottom, :url_list, :partial => "url_form", :object => Url.new } %>

This code takes advantage of Rails view helpers and assumes that you are using Prototype. It also does not account for removing URLs from the list. I doubt it will work exactly as written, but I hope you get the general idea on how to this. Immediate improvements I would recommend would be to make the JavaScript unobtrusive.

The Complex Forms Railscasts are not specifically about this problem, but Ryan does include dynamic addition of forms that is a good example to follow.

Good Luck!

Peer Allan