Project

General

Profile

Feature #33418 » relations_bulk_create.patch

Dmitry Makurin , 2020-05-08 12:17

View differences:

app/controllers/issue_relations_controller.rb (revision 27923fae6ba1509f770a95a3609c01f73288732b)
44 44
  end
45 45

  
46 46
  def create
47
    @relation = IssueRelation.new
48
    @relation.issue_from = @issue
49
    @relation.safe_attributes = params[:relation]
50
    @relation.init_journals(User.current)
47
    saved = nil
48
    bulk_relations ||= []
49

  
50
    relation_issues_to_id.each do |issue_to_id|
51
      @relation = IssueRelation.new
52
      @relation.issue_from = @issue
53
      @relation.safe_attributes = params[:relation]
54
      @relation.issue_to = Issue.visible(User.current).find_by_id(issue_to_id.delete('^0-9'))
55
      @relation.init_journals(User.current)
51 56

  
52
    begin
53
      saved = @relation.save
54
    rescue ActiveRecord::RecordNotUnique
55
      saved = false
56
      @relation.errors.add :base, :taken
57
      begin
58
        saved = @relation.save
59
      rescue ActiveRecord::RecordNotUnique
60
        saved = false
61
        @relation.errors.add :base, :taken
62
      end
63
      bulk_relations << @relation
64
      @relation_errors = bulk_relations.map {|o| o.errors.full_messages}.flatten
57 65
    end
58 66

  
59 67
    respond_to do |format|
......
97 105
  rescue ActiveRecord::RecordNotFound
98 106
    render_404
99 107
  end
108

  
109
  def relation_issues_to_id
110
    issue_to_id = params[:relation].require(:issue_to_id)
111
    issue_to_id = issue_to_id.scan(/#?[0-9]+,?/)
112
    raise Unauthorized if issue_to_id.size.zero?
113

  
114
    issue_to_id
115
  rescue ActionController::ParameterMissing => e
116
    render_error(:message => e.message, :status => 400)
117
    []
118
  end
100 119
end
app/models/issue_relation.rb (revision 27923fae6ba1509f770a95a3609c01f73288732b)
89 89
    end
90 90

  
91 91
    return unless attrs.is_a?(Hash)
92

  
92 93
    attrs = attrs.deep_dup
93

  
94
    if issue_id = attrs.delete('issue_to_id')
95
      if issue_id.to_s.strip.match(/\A#?(\d+)\z/)
96
        issue_id = $1.to_i
97
        self.issue_to = Issue.visible(user).find_by_id(issue_id)
98
      end
99
    end
100

  
101 94
    super(attrs)
102 95
  end
103 96

  
app/views/issue_relations/_form.html.erb (revision 27923fae6ba1509f770a95a3609c01f73288732b)
1
<%= error_messages_for 'relation' %>
1
<%= render_error_messages(@relation_errors) if @relation_errors %>
2 2

  
3 3
<p><%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %>
4 4
<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :size => 10 %>
test/functional/issue_relations_controller_test.rb (revision 27923fae6ba1509f770a95a3609c01f73288732b)
55 55
    assert_equal 'relates', relation.relation_type
56 56
  end
57 57

  
58
  def test_bulk_create
59
    assert_difference 'IssueRelation.count', +3 do
60
      post :create, :params => {
61
          :issue_id => 1,
62
          :relation => {
63
              :issue_to_id => '2,3,7',
64
              :relation_type => 'relates',
65
              :delay => ''
66
          }
67
      }
68
    end
69
    relations = IssueRelation.where(:issue_from_id => 1, :issue_to_id => [2,3,7])
70
    assert_equal 3, relations.count
71
    # all relations types should be 'relates'
72
    relations.map { |r| assert_equal 'relates', r.relation_type }
73
  end
74

  
75
  def test_bulk_create_should_show_errors
76
      assert_difference 'IssueRelation.count', +3 do
77
        post :create, :params => {
78
            :issue_id => 1,
79
            :relation => {
80
                :issue_to_id => '2,3,4,5,7',
81
                :relation_type => 'relates',
82
                :delay => ''
83
            }
84
        },
85
        :xhr => true
86
      end
87
      assert_response :success
88
      assert_equal 'text/javascript', response.media_type
89

  
90
      # issues #4 and #5 can't be related by default
91
      assert_include 'Related issue cannot be blank', response.body
92
      assert_include 'Related issue doesn&#39;t belong to the same project', response.body
93
  end
94

  
58 95
  def test_create_on_invalid_issue
59 96
    assert_no_difference 'IssueRelation.count' do
60 97
      post :create, :params => {
(1-1/5)