Christos Zisopoulos
2006-Apr-05 23:13 UTC
[Rails] CRUD pattern for has_many relationships (forms containing collections)?
Hello folks! Beare with me for a second, while I explain my problem. Assuming we have the trivial model of class Author has_many :books end class Book end How do people go about creating the authors/edit and authors/new views if you want to be able to add and remove arbitrary amount of Books at Author creation and edit time? What I mean by this is that I go to ''authors/new'' then add a few Books and then create the Author. Let''s assume that I am using link_to_remote for the on the fly addition of Books to the Author. It is important that neither the Author nor the Books are saved to the database until the Create form button is pressed. My solution so far is to use the session object to keep an Array with new Books that are not saved in the database. I have a books/_book.rhtml partial <p><%= text_field_tag "books[#{book.id}][title]", book.title %></p> ...an authors/_form.rhtml partial <%= text_field "author", "name" %> <%= link_to_remote "Add book", :url => {:action => "add_book"} :update => "books_list" %> <div id="books_list"> <%= render :partial => "books/book", :collection => author.books %> </div> ...and in authors_controller.rb def new session[:books] = Array.new end def add_book book = Book.new(:title => "untitled") book.id = -session[:books].size session[:books] << book render :partial => "books/book", :collection => session[:books] end def create # code ommited but.. # I look for session[:books] and iterate through each adding a new one if it has a # negative id, otherwise find the exisiting book (when coming from an edit) end The above approach breaks down when adding books because book.id is not defined yet. The ugly hack is that I am setting the id to a negative value so that I can then spot it in my create method and create proper Book objects. The above works for the edit mode. This gets even messier if you have Chapters and a Book has_many chapters. There seems to be no recursive way of creating and then parsing all these. -christos
Adam Bloom
2006-Apr-06 04:22 UTC
[Rails] Re: CRUD pattern for has_many relationships (forms containin
Hmmm. Well I''m sure exactly what your problem is, and I don''t know how attached you are to your links approach to adding books, but this is the checkbox form I have for a similar structure: (listings habtm categories) <% for category in @categories %> <div id="category"> <input type="checkbox" id="<%= category.id %>" name="category_ids[]" value="<%= category.id %>" <% if @listing.categories.include? category %>checked="checked"<% end %> ></a> <%= h(category.name) %> </div> <% end %> Then in the create code I have: @listing.categories = Category.find(params[:category_ids]) The same can work for a book with chapters. I hope this helps. -Adam -- Posted via http://www.ruby-forum.com/.
Adam Bloom
2006-Apr-06 04:23 UTC
[Rails] Re: CRUD pattern for has_many relationships (forms containin
That first line should read, "I''m NOT sure exactly what your problem is..." >_> -- Posted via http://www.ruby-forum.com/.
Christos Zisopoulos
2006-Apr-06 09:31 UTC
[Rails] Re: CRUD pattern for has_many relationships (forms containin
Hello Adam. Maybe I didn''t explain my problem very well. I know how to add EXISTING books to a new author at creation time, like you showed below. What I need though is to be able to create one or more NEW books when creating a new Author. The books can have more than just one attribute (e.g. name, isbn, num_of_pages). And I need to do it inline in my Author form. -christos On 6 Apr 2006, at 05:22, Adam Bloom wrote:> Hmmm. Well I''m sure exactly what your problem is, and I don''t know how > attached you are to your links approach to adding books, but this > is the > checkbox form I have for a similar structure: > > (listings habtm categories) > > <% for category in @categories %> > <div id="category"> > <input type="checkbox" > id="<%= category.id %>" > name="category_ids[]" > value="<%= category.id %>" > <% if @listing.categories.include? category %>checked="checked"< > % end > %> > ></a> <%= h(category.name) %> > </div> > <% end %> > > Then in the create code I have: > > @listing.categories = Category.find(params[:category_ids]) > > The same can work for a book with chapters. I hope this helps. > > -Adam > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails