I'm writing a Rails app that uses a custom model class to interact with Apache CouchDB via couchrest. The app is very schemaless in nature, which is one of the reasons I'm using CouchDB in the first place.
Rails' form_for
expects models that have methods for all its attributes. This is a problem, since my custom model doesn't define methods for the attributes. It stores data in a hash, and provides hash-like methods ([]
and []=
) to access data. Creating methods for my attributes are not viable, since I don't know which attributes my models have beforehand, when I want forms for @user = User.new
, for example.
So a form like this:
<%= form_for @user, :path => session_path do |f| %>
<%= f.form_for :name %>
<% end %>
Basically ends up doing this:
@user.send("name")
What I need it to do, is this:
@user[:name]
To change this behaviour, we unfortunately need to monkey patch. I haven't found any APIs for it, and it boils down to a unconfigurable low level class called ActionView::Helpers::InstanceTag
, so creating a custom form_for
isn't viable.
I added the snippet below to config/initializers/monkey_patches.rb.
class ActionView::Helpers::InstanceTag
def self.value(object, method_name)
object[method_name.to_sym] if object
end
def self.value_before_type_cast(object, method_name)
self.value(object, method_name)
end
end
Here's the original source code on GitHub for these two methods. As you can see, my particular implementation may not solve your problems, and ignores the _before_type_cast
stuff since my particular model class doesn't do type casting.
I did not investigate why method_name
is a string, given I originally specified it as a symbol in f.text_field
.