Reputation: 2093
I have a tableless model that I'm trying to generate some form fields for.
The form looks like so:
= form_for :users, url: users_path do |f|
- books.each do |book|
= f.fields_for :books, book do |bf|
= bf.hidden_field :title, value: book.title
= f.submit "Send"
What I'm expecting to be generated for each field is something like this:
<input name="users[books][][title]" type="hidden" value="Some Book Title">
<input name="users[books][][title]" type="hidden" value="Some Book Title">
<input name="users[books][][title]" type="hidden" value="Some Book Title">
However, what I'm actually getting is
<input name="users[books][title]" type="hidden" value="Some Book Title">
<input name="users[books][title]" type="hidden" value="Some Book Title">
<input name="users[books][title]" type="hidden" value="Some Book Title">
Which means when the form is submitted only the last input field is available as the previous two have been overwritten due to them referencing the same thing.
This works ok when the model has an active record backend but not when it's tableless.
Any suggestions?
Upvotes: 5
Views: 1268
Reputation: 4383
Right now this is pretty hard to do with Rails 3.x. That will change with Rails 4 with the advent of ActiveModel::Model
which will give all the base methods for your model to be ActionPack
compatable.
However until Rails 4 is released a good standard to make your model ActionPack
compatible is the ActionModel::Model
module itself. It "should" work with the current stable Rails. Check it out
How you choose to implement this is your decision, but I would probably just download the file and throw it in my application's lib
directory. That way I could just include it using
class Book
include ActiveModel::Model
end
Easy Rails Form compatibility for custom models.
Upvotes: 0
Reputation: 1397
Welldan97 brings up a very important point. You need the persisted? method. I was getting an undefined method for the model name earlier. Check my gist out. It works, but not perfect by any means. https://gist.github.com/2638002
Upvotes: 0
Reputation: 3076
I think you need to add this to your users model
def books_attributes= attributes
# do something with attributes
# probably:
# self.books = attributes.map{|k,v|Book.new(v)}
end
And also define persisted?
method for Book instance. Make it just to return false
.
And add f
for your fields_for
in view:
= f.fields_for :books, book do |bf|
I hope this will work.
Upvotes: 7