Using Rails Form Helpers with Serialized Custom Classes

How to edit Rails serialized hashes in a form?

Option 1: Single instance method to update serialized attribute

As far as I know it's not possible to edit directly from a form a serialized attribute.

When I have this kind of things I'm always creating an instance method in the model that receive params and do the update (Could also do the save if I end the method name with a bang (!)).

In your case I would do the following:

class Bulletin

...

def update_top_offices!(params)
params.each do |key, value|
self.top_offices[key] = value
end

self.save
end

...
end

Option 2: A getter/setter per serialized attribute keys

Also another possibility if you really want to use a form to update the serialized attribute is to create a getter/setter as following:

class Bulletin

...

def first_office
self.top_offices[:first_office]
end

def first_office=(value)
self.top_offices[:first_office] = value
end

...
end

But then don't forget to save updated values.

Options 3: Overriding method_missing

A last possibility is to override method_missing but it's a bit more complex.

Is it possible to create form for simple class

jdc answered this, but didn't show the actual implementation you requested. As jdc stated you need to include some ActiveModel modules, which will give your ruby class the features you need.

It looks like you need ActiveModel::Naming and ActiveModel::AttributeMethods.

class Entry
extend ActiveModel::Naming
include ActiveModel::AttributeMethods
end

The first line will give you model_name and the second line allow your model to function with the form helpers. There are other lines you can use: check the blog posted linked in jdc's answer or the Rails API.

More links with detailed information:

http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html

http://railscasts.com/episodes/219-active-model

How to include both a class and data attributes in a form select in Rails 7?

A hash looks like this: { key1: value1, key2: value2 }

So, take your attempted code: { { class: "class_name" } } - the inner hash there is { class: "class_name" } so let's assign that to a variable: value1 = { class: "class_name" } and then let's use that variable in your attempted code: { value1 }

See how that's not a hash, there's no key for the value. A hash must always have keys and values. This is why you're getting the syntax errors in your second two examples.

So let me go through your other two attempts:

<%= f.select(:repeat, Batch.repeats, {class: "class_name"}, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}) %>

So here, :repeat is the first argument, Batch.repeats is the second, the third argument (which is supposed to be the select options) is the hash with a single key/value pair: { class: "class_name" }, and the fourth argument (which is supposed to be the html options) is the hash with a single key/value pair: { data: { the: data, hash: here }

Your second attempt:

<%= f.select(:repeat, Batch.repeats, { data: { batch_repeat_target: "input", action: "change->batch-repeat#toggle" }}, { class: "class_name" }) %>

First two arguments the same, the third argument (the select options) is now the hash with the :data key/value, and the fourth argument (the html options) is now the hash with the single :class key/value.

What you want to do is provide an empty hash for the third argument (the select options), and then a hash with TWO key/value pairs for the fourth argument (the html options):

{ class: "class_name", data: { the: data, hash: here } }

(Note, I intentionally didn't feed you the full answer, because I feel that you're the sort of person who will benefit from discovering it on your own, but say so if I've misjudged, happy to edit this answer if you need it)



Related Topics



Leave a reply



Submit