0

I'm new to Ruby on Rails and i'm trying to create a plugin. As a first step, I'm trying to modify the User Account page with a new form field. So far, I have the field and if I manually insert data for it in the DB, it gets pre-populated, however, I can not get it to Save data that is entered.

I'm using the view_my_account hook. I also have validation setup in my patch using validates_presence_of. It throws an error when i submit an empty field, and a populated field -- I assume because the field isn't connecting correctly with the @user.save in Redmine

here's what I have:

init.rb

require 'redmine'

# Patches to Redmine Core
require 'user_patch'

# Hooks
require_dependency 'account_view_hook'

Redmine::Plugin.register :myTest do
 # all plugin info
end

plugins/myTest/lib/user_patch.rb

require_dependency 'user'

module UserPatch
    def self.included(base)
        base.extend(ClassMethods)

        base.send(:include, InstanceMethods)

        base.class_eval do
            unloadable

            validates_presence_of :my_new_field

        end
    end

    module ClassMethods
    end

    module InstanceMethods
    end
end

ActionDispatch::Callbacks.to_prepare do
  User.send(:include, UserPatch)
end

plugins/myTest/lib/account_view_hook.rb

class AccountViewHook < Redmine::Hook::ViewListener
  render_on :view_my_account, :partial => 'account/my_new_field'
end

plugins/myTest/app/views/account/_my_new_field.html.erb

<p><%= form.text_field :my_new_field, :required => true %></p>

and the original page into which I'm hooking (redmine/app/views/my/account.html.erb)

<div class="contextual">
<%= additional_emails_link(@user) %>
<%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %>
<%= call_hook(:view_my_account_contextual, :user => @user)%>
</div>

<h2>
  <%= avatar_edit_link(@user, :size => "50") %>
  <%=l(:label_my_account)%>
</h2>

<%= error_messages_for 'user' %>

<%= labelled_form_for :user, @user,
                     :url => { :action => "account" },
                     :html => { :id => 'my_account_form',
                                :method => :post } do |f| %>
<div class="splitcontentleft">
<fieldset class="box tabular">
  <legend><%=l(:label_information_plural)%></legend>
  <p><%= f.text_field :firstname, :required => true %></p>
  <p><%= f.text_field :lastname, :required => true %></p>
  <p><%= f.text_field :mail, :required => true %></p>
  <% unless @user.force_default_language? %>
  <p><%= f.select :language, lang_options_for_select %></p>
  <% end %>
  <% if Setting.openid? %>
  <p><%= f.text_field :identity_url  %></p>
  <% end %>

  <% @user.custom_field_values.select(&:editable?).each do |value| %>
    <p><%= custom_field_tag_with_label :user, value %></p>
  <% end %>
  <%= call_hook(:view_my_account, :user => @user, :form => f) %>
</fieldset>

<%= submit_tag l(:button_save) %>
</div>

<div class="splitcontentright">
<fieldset class="box">
  <legend><%=l(:field_mail_notification)%></legend>
  <%= render :partial => 'users/mail_notifications' %>
</fieldset>

<fieldset class="box tabular">
  <legend><%=l(:label_preferences)%></legend>
  <%= render :partial => 'users/preferences' %>
  <%= call_hook(:view_my_account_preferences, :user => @user, :form => f) %>
</fieldset>

</div>
<% end %>

<% content_for :sidebar do %>
<%= render :partial => 'sidebar' %>
<% end %>

<% html_title(l(:label_my_account)) -%>

1 Answer 1

1

New field must be added to model first.

Commonly in Ruby on Rails You must generate and run migration, only then field performing will work.

But Redmine supports its models extension without migration and even without programming. If You want add field to user model, use custom fields that can be added in Redmine adminstrative settings. New field will be shown in user forms immediately, without Redmine restarting.

Of course You can use view hooks to view field as You need to and change standart performing of your field. See my answer for how to work with custom field values.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for that. I did actually run a migration a babe the new field in the database. I had read about custom fields, but was curious to try and accomplish it with migrations. In that case, what am I missing?
Can You show migration code? Was migration successful and field added? Also I think that You must set field value in UsersController before saving (at create and update methods)
User gives values at @user.safe_attributes = params[:user] row in UsersController. Maybe your field can't get value because of this row - inside it calls delete_unsafe_attributes method that perhaps cuts your value as unsafe
the migration was successful. I thought simiarly about @user.safe_attributes. This page is actually dealt with through my_controller.rb, but it has a similar line: @user.safe_attributes = params[:user] if params[:user] So how do I set my new attribute to be safe?
ah found it! I added this to user_patch.rb: User.safe_attributes 'my_new_field'. Thanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.