0xCAFEBABE
0xCAFEBABE

Reputation: 5666

Creating and populating Redmine custom fields by ruby code

We are developing a mogration from a small issue tracker software to Redmine. We use the Ruby classes directly to migrate the data. The class for an issue is defined like this:

  class BuggyIssue < ActiveRecord::Base
    self.table_name = :issues
    belongs_to :last_issue_change, :class_name => 'BuggyIssueChange', :foreign_key => 'last_issue_change_id'
    has_many :issue_changes, :class_name => 'BuggyIssueChange', :foreign_key => 'issue_id', :order => 'issue_changes.date DESC'
    set_inheritance_column :none

    # Issue changes: only migrate status changes and comments
    has_many :issue_changes, :class_name => "BuggyIssueChange", :foreign_key => :issue_id

    def attachments
      #BuggyMigrate::BuggyAttachment.all(:conditions => ["type = 'issue' AND id = ?", self.id.to_s])
    end

    def issue_type
      read_attribute(:type)
    end

    def summary
      read_attribute(:summary).blank? ? "(no subject)" : read_attribute(:summary)
    end

    def description
      read_attribute(:description).blank? ? summary : read_attribute(:description)
    end

    def time; Time.at(read_attribute(:time)) end
    def changetime; Time.at(read_attribute(:changetime)) end
  end

Creating an issue and defining custom fields for the issue works. However, populating the custom fields doesn't seem to work. There are 4 custom fields (Contact, Test status, Source and Resolution).

The custom fields are created like this:

    repf = IssueCustomField.find_by_name("Contact")
    repf ||= IssueCustomField.create(:name => "Contact", :field_format => 'string') if repf.nil?
    repf.trackers = Tracker.find(:all)
    repf.projects << product_map.values
    repf.save!

The values for these fields are passed like this:

i = Issue.new :project => product_map[first_change.product_id],
...
:custom_field_values => {:Contact => issue.contact, 'Test status' => '', :Source => '', :Resolution => ''}

I've also tried a version with an index as hash key:

:custom_field_values => {'1' => issue.contact, 'Test status' => '', :Source => '', :Resolution => ''}

The issue can be saved without an issue, however, no value is ever passed over to Redmine. A

mysql> select count(*) from custom_values where value is not null;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.01 sec)

shows that all values for the custom fields are NULL after the migration. I don't seem to be able to find how this is done correctly, the documentation for the Redmine classes is very sparse.

Upvotes: 1

Views: 3675

Answers (1)

Noma4i
Noma4i

Reputation: 770

I spent much time to solve near same issue. Take a look on my code written to transfer data from old system to new via Redmine REST API. Cause I used ActiveResource code will be usable for you.

def update_custom_fields(issue, fields)
    f_id = Hash.new { |hash, key| hash[key] = nil }
    issue.available_custom_fields.each_with_index.map { |f,indx| f_id[f.name] = f.id }
    field_list = []
    fields.each do |name, value|
      field_id = f_id[name].to_s
      field_list << Hash[field_id, value]
    end
    issue.custom_field_values = field_list.reduce({},:merge)

    raise issue.errors.full_messages.join(', ') unless issue.save
end

Now you can just call update_custom_fields(Issue.last, "MyField" => "MyValue" .. and so on)

Upvotes: 2

Related Questions