##// END OF EJS Templates
Makes relations resource shallow (#7366)....
Jean-Philippe Lang -
r6064:42f9dc7d2c5a
parent child
Show More
@@ -16,7 +16,9
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class IssueRelationsController < ApplicationController
18 class IssueRelationsController < ApplicationController
19 before_filter :find_issue, :find_project_from_association, :authorize
19 before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create]
20 before_filter :find_relation, :except => [:index, :create]
21
20 accept_key_auth :index, :show, :create, :destroy
22 accept_key_auth :index, :show, :create, :destroy
21
23
22 def index
24 def index
@@ -29,7 +31,7 class IssueRelationsController < ApplicationController
29 end
31 end
30
32
31 def show
33 def show
32 @relation = @issue.find_relation(params[:id])
34 raise Unauthorized unless @relation.visible?
33
35
34 respond_to do |format|
36 respond_to do |format|
35 format.html { render :nothing => true }
37 format.html { render :nothing => true }
@@ -62,7 +64,7 class IssueRelationsController < ApplicationController
62 end
64 end
63 format.api {
65 format.api {
64 if saved
66 if saved
65 render :action => 'show', :status => :created, :location => issue_relation_url(@issue, @relation)
67 render :action => 'show', :status => :created, :location => relation_url(@relation)
66 else
68 else
67 render_validation_errors(@relation)
69 render_validation_errors(@relation)
68 end
70 end
@@ -72,16 +74,13 class IssueRelationsController < ApplicationController
72
74
73 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
75 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
74 def destroy
76 def destroy
75 relation = @issue.find_relation(params[:id])
77 raise Unauthorized unless @relation.deletable?
76 relation.destroy
78 @relation.destroy
77
79
78 respond_to do |format|
80 respond_to do |format|
79 format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
81 format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
80 format.js {
82 format.js { render(:update) {|page| page.remove "relation-#{@relation.id}"} }
81 @relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
83 format.api { head :ok }
82 render(:update) {|page| page.replace_html "relations", :partial => 'issues/relations'}
83 }
84 format.api { head :ok }
85 end
84 end
86 rescue ActiveRecord::RecordNotFound
85 rescue ActiveRecord::RecordNotFound
87 render_404
86 render_404
@@ -93,4 +92,10 private
93 rescue ActiveRecord::RecordNotFound
92 rescue ActiveRecord::RecordNotFound
94 render_404
93 render_404
95 end
94 end
95
96 def find_relation
97 @relation = IssueRelation.find(params[:id])
98 rescue ActiveRecord::RecordNotFound
99 render_404
100 end
96 end
101 end
@@ -43,6 +43,16 class IssueRelation < ActiveRecord::Base
43
43
44 attr_protected :issue_from_id, :issue_to_id
44 attr_protected :issue_from_id, :issue_to_id
45
45
46 def visible?(user=User.current)
47 (issue_from.nil? || issue_from.visible?(user)) && (issue_to.nil? || issue_to.visible?(user))
48 end
49
50 def deletable?(user=User.current)
51 visible?(user) &&
52 ((issue_from.nil? || user.allowed_to?(:manage_issue_relations, issue_from.project)) ||
53 (issue_to.nil? || user.allowed_to?(:manage_issue_relations, issue_to.project)))
54 end
55
46 def after_initialize
56 def after_initialize
47 if new_record?
57 if new_record?
48 if relation_type.blank?
58 if relation_type.blank?
@@ -2,6 +2,6 api.relation do
2 api.id @relation.id
2 api.id @relation.id
3 api.issue_id @relation.issue_from_id
3 api.issue_id @relation.issue_from_id
4 api.issue_to_id @relation.issue_to_id
4 api.issue_to_id @relation.issue_to_id
5 api.relation_type @relation.relation_type_for(@issue)
5 api.relation_type @relation.relation_type
6 api.delay @relation.delay
6 api.delay @relation.delay
7 end
7 end
@@ -10,7 +10,7
10 <form>
10 <form>
11 <table class="list issues">
11 <table class="list issues">
12 <% @relations.each do |relation| %>
12 <% @relations.each do |relation| %>
13 <tr class="issue hascontextmenu">
13 <tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
14 <td class="checkbox"><%= check_box_tag("ids[]", relation.other_issue(@issue).id, false, :id => nil) %></td>
14 <td class="checkbox"><%= check_box_tag("ids[]", relation.other_issue(@issue).id, false, :id => nil) %></td>
15 <td class="subject"><%= l(relation.label_for(@issue)) %> <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
15 <td class="subject"><%= l(relation.label_for(@issue)) %> <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
16 <%= h(relation.other_issue(@issue).project) + ' - ' if Setting.cross_project_issue_relations? %>
16 <%= h(relation.other_issue(@issue).project) + ' - ' if Setting.cross_project_issue_relations? %>
@@ -19,7 +19,7
19 <td class="status"><%= relation.other_issue(@issue).status.name %></td>
19 <td class="status"><%= relation.other_issue(@issue).status.name %></td>
20 <td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
20 <td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
21 <td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
21 <td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
22 <td class="buttons"><%= link_to_remote(image_tag('link_break.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :issue_id => @issue, :id => relation},
22 <td class="buttons"><%= link_to_remote(image_tag('link_break.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :id => relation},
23 :method => :delete
23 :method => :delete
24 }, :title => l(:label_relation_delete)) if authorize_for('issue_relations', 'destroy') %></td>
24 }, :title => l(:label_relation_delete)) if authorize_for('issue_relations', 'destroy') %></td>
25 </tr>
25 </tr>
@@ -110,7 +110,7 ActionController::Routing::Routes.draw do |map|
110
110
111 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
111 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
112 issues.resources :time_entries, :controller => 'timelog'
112 issues.resources :time_entries, :controller => 'timelog'
113 issues.resources :relations, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
113 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
114 end
114 end
115
115
116 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
116 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
@@ -97,7 +97,7 class IssueRelationsControllerTest < ActionController::TestCase
97 def test_destroy
97 def test_destroy
98 assert_difference 'IssueRelation.count', -1 do
98 assert_difference 'IssueRelation.count', -1 do
99 @request.session[:user_id] = 3
99 @request.session[:user_id] = 3
100 delete :destroy, :id => '2', :issue_id => '3'
100 delete :destroy, :id => '2'
101 end
101 end
102 end
102 end
103
103
@@ -109,11 +109,8 class IssueRelationsControllerTest < ActionController::TestCase
109
109
110 assert_difference 'IssueRelation.count', -1 do
110 assert_difference 'IssueRelation.count', -1 do
111 @request.session[:user_id] = 3
111 @request.session[:user_id] = 3
112 xhr :delete, :destroy, :id => '2', :issue_id => '3'
112 xhr :delete, :destroy, :id => '2'
113 assert_select_rjs 'relations' do
113 assert_select_rjs :remove, 'relation-2'
114 assert_select 'table', 1
115 assert_select 'tr', 1 # relation left
116 end
117 end
114 end
118 end
115 end
119 end
116 end
@@ -73,10 +73,10 class ApiTest::IssueRelationsTest < ActionController::IntegrationTest
73 end
73 end
74 end
74 end
75
75
76 context "/issues/:issue_id/relations/:id" do
76 context "/relations/:id" do
77 context "GET" do
77 context "GET" do
78 should "return the relation" do
78 should "return the relation" do
79 get '/issues/3/relations/2.xml', {}, :authorization => credentials('jsmith')
79 get '/relations/2.xml', {}, :authorization => credentials('jsmith')
80
80
81 assert_response :success
81 assert_response :success
82 assert_equal 'application/xml', @response.content_type
82 assert_equal 'application/xml', @response.content_type
@@ -87,7 +87,7 class ApiTest::IssueRelationsTest < ActionController::IntegrationTest
87 context "DELETE" do
87 context "DELETE" do
88 should "delete the relation" do
88 should "delete the relation" do
89 assert_difference('IssueRelation.count', -1) do
89 assert_difference('IssueRelation.count', -1) do
90 delete '/issues/3/relations/2.xml', {}, :authorization => credentials('jsmith')
90 delete '/relations/2.xml', {}, :authorization => credentials('jsmith')
91 end
91 end
92
92
93 assert_response :ok
93 assert_response :ok
@@ -126,13 +126,13 class RoutingTest < ActionController::IntegrationTest
126 should_route :post, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'xml'
126 should_route :post, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'xml'
127 should_route :post, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'json'
127 should_route :post, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'json'
128
128
129 should_route :get, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23'
129 should_route :get, "/relations/23", :controller => 'issue_relations', :action => 'show', :id => '23'
130 should_route :get, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'xml'
130 should_route :get, "/relations/23.xml", :controller => 'issue_relations', :action => 'show', :id => '23', :format => 'xml'
131 should_route :get, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'json'
131 should_route :get, "/relations/23.json", :controller => 'issue_relations', :action => 'show', :id => '23', :format => 'json'
132
132
133 should_route :delete, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23'
133 should_route :delete, "/relations/23", :controller => 'issue_relations', :action => 'destroy', :id => '23'
134 should_route :delete, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'xml'
134 should_route :delete, "/relations/23.xml", :controller => 'issue_relations', :action => 'destroy', :id => '23', :format => 'xml'
135 should_route :delete, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'json'
135 should_route :delete, "/relations/23.json", :controller => 'issue_relations', :action => 'destroy', :id => '23', :format => 'json'
136 end
136 end
137
137
138 context "issue reports" do
138 context "issue reports" do
General Comments 0
You need to be logged in to leave comments. Login now