Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override a form field value in rails form

Note: I was overthinking things when I originally asked this question. The accepted answer is correct for the examples I gave - i.e. you can just pass :value to text_field, however I'd actually been having problems with date_select, which doesn't have a facility to override the value set.

As a result this has now been updated in Rails, so you can set :selected => a_date, and it will work as expected. This will be in Rails 4.


I have a model that can inherit its value from a parent model. It works something like this:

class User < ActiveRecord::Base
  attr_accessible :field_name

  belongs_to :company

  def field_name
    if self['field_name'].nil?
      company['field_name']
    else
      self['field_name']
    end
  end

end

class Company < ActiveRecord::Base
  attr_accessible :field_name
end

I then have a form to edit the User, but of course, if the User value is nil, then it populates the form with the value from Company, which is not what I want.

I would like to be able to override the value of the form field, so that if the User value is nil, then the value is empty.

Attempt 1

Ideally I'd be able to do:

<%= form_for @user do |f| %>
   <%= f.text_field :field_name, @user['field_name'] %>
<% end %>

But that doesn't work, there doesn't seem to be a mechanism for providing an override value.

Attempt 2

So I thought about creating a second getter/setter:

def field_name_uninherited
  self['field_name']
end

def field_name_uninherited=(value)
  self['field_name']=value
end

Now I can use <%= f.text_field :field_name_uninherited %> and it works as expected - great! Except: when field_name is a date, or other type using multiparameter attributes, it results in this error:

1 error(s) on assignment of multiparameter attributes

I believe this is because it doesn't know that this is a date field, as it infers this from the database, and this field (with _uninherited suffix) is not in the database.

So I need some way to mark my additional method as the same type as the original database field.


A further note, the above examples (using field_name) are a simplified version. I'm actually using https://github.com/colinbm/inherits_values_from to handle the inheritance, but I don't think this is important to the question.


Obviously if there's a better way to accomplish the same goal, then I'm all ears.

like image 366
Colin Avatar asked Dec 07 '22 10:12

Colin


2 Answers

So when it comes to displaying the value you for a user you want it to behave a bit differently?

What I'd do is use the :value option with your form field. That way you get to set the value like normal but choose what you want displayed in the form field.

<%= f.text_field :company, :value => user.field_name_uninherited %>
like image 65
digitalWestie Avatar answered Mar 06 '23 03:03

digitalWestie


For what I understand, you want the user to put the field data and only if it's nil, populate that value with the parent (company) model. It seems to me before_save works perfectly, because it is called (as it name proposes) just before the save method is called on an ActiveRecord object. Thus you can write this kind of callback:

    class User < ActiveRecord::Base
      attr_accessible :field_name

      before_save :override_field

      private
        def override_field
          if self.field_name.nil?
            self.field_name = company.field_name
          end
        end

This way, you'll be only overriding the value if it's nil at the moment of saving, leaving that form field empty at the moment of creating a new element. Hope this works!

like image 44
CristianDonosoC Avatar answered Mar 06 '23 05:03

CristianDonosoC