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)) -%>
General Failure
  • 2,421
  • 4
  • 23
  • 49
djt
  • 7,297
  • 11
  • 55
  • 102

1 Answers1

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.

Community
  • 1
  • 1
General Failure
  • 2,421
  • 4
  • 23
  • 49
  • 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? – djt Oct 14 '15 at 05:15
  • 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) – General Failure Oct 14 '15 at 05:22
  • 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 – General Failure Oct 14 '15 at 06:00
  • 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? – djt Oct 14 '15 at 14:04
  • ah found it! I added this to `user_patch.rb`: `User.safe_attributes 'my_new_field'`. Thanks for your help! – djt Oct 14 '15 at 14:10