summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-10-22 17:37:16 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-10-22 17:37:16 +0000
commit2d1866d966d94c688f9cb87c5bf3f096dffac844 (patch)
tree7a733c1cc51448ab69b3f892285305dbfb0ae15e /app
parenta6ec78a4dc658e3517ed682792016b6530458696 (diff)
downloadredmine-2d1866d966d94c688f9cb87c5bf3f096dffac844.tar.gz
redmine-2d1866d966d94c688f9cb87c5bf3f096dffac844.zip
Merged rails-4.1 branch (#14534).
git-svn-id: http://svn.redmine.org/redmine/trunk@13482 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin_controller.rb2
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/auto_completes_controller.rb2
-rw-r--r--app/controllers/boards_controller.rb9
-rw-r--r--app/controllers/documents_controller.rb6
-rw-r--r--app/controllers/enumerations_controller.rb6
-rw-r--r--app/controllers/files_controller.rb6
-rw-r--r--app/controllers/groups_controller.rb6
-rw-r--r--app/controllers/issue_categories_controller.rb2
-rw-r--r--app/controllers/issue_statuses_controller.rb2
-rw-r--r--app/controllers/issues_controller.rb21
-rw-r--r--app/controllers/journals_controller.rb1
-rw-r--r--app/controllers/members_controller.rb7
-rw-r--r--app/controllers/messages_controller.rb4
-rw-r--r--app/controllers/my_controller.rb4
-rw-r--r--app/controllers/news_controller.rb2
-rw-r--r--app/controllers/project_enumerations_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb26
-rw-r--r--app/controllers/queries_controller.rb3
-rw-r--r--app/controllers/reports_controller.rb2
-rw-r--r--app/controllers/repositories_controller.rb6
-rw-r--r--app/controllers/roles_controller.rb10
-rw-r--r--app/controllers/search_controller.rb2
-rw-r--r--app/controllers/sys_controller.rb5
-rw-r--r--app/controllers/timelog_controller.rb10
-rw-r--r--app/controllers/trackers_controller.rb6
-rw-r--r--app/controllers/users_controller.rb8
-rw-r--r--app/controllers/versions_controller.rb8
-rw-r--r--app/controllers/watchers_controller.rb4
-rw-r--r--app/controllers/wiki_controller.rb14
-rw-r--r--app/controllers/workflows_controller.rb14
-rw-r--r--app/helpers/application_helper.rb28
-rw-r--r--app/helpers/groups_helper.rb2
-rw-r--r--app/helpers/issues_helper.rb6
-rw-r--r--app/helpers/members_helper.rb2
-rw-r--r--app/helpers/my_helper.rb21
-rw-r--r--app/helpers/projects_helper.rb5
-rw-r--r--app/helpers/queries_helper.rb2
-rw-r--r--app/helpers/search_helper.rb1
-rw-r--r--app/helpers/sort_helper.rb3
-rw-r--r--app/helpers/timelog_helper.rb2
-rw-r--r--app/models/attachment.rb15
-rw-r--r--app/models/auth_source.rb1
-rw-r--r--app/models/board.rb9
-rw-r--r--app/models/change.rb1
-rw-r--r--app/models/changeset.rb9
-rw-r--r--app/models/comment.rb1
-rw-r--r--app/models/custom_field.rb5
-rw-r--r--app/models/custom_value.rb1
-rw-r--r--app/models/document.rb10
-rw-r--r--app/models/enabled_module.rb1
-rw-r--r--app/models/enumeration.rb2
-rw-r--r--app/models/group.rb8
-rw-r--r--app/models/group_anonymous.rb4
-rw-r--r--app/models/group_builtin.rb2
-rw-r--r--app/models/group_non_member.rb4
-rw-r--r--app/models/issue.rb75
-rw-r--r--app/models/issue_category.rb1
-rw-r--r--app/models/issue_custom_field.rb2
-rw-r--r--app/models/issue_query.rb34
-rw-r--r--app/models/issue_status.rb3
-rw-r--r--app/models/journal.rb12
-rw-r--r--app/models/journal_detail.rb1
-rw-r--r--app/models/mail_handler.rb4
-rw-r--r--app/models/member.rb1
-rw-r--r--app/models/member_role.rb1
-rw-r--r--app/models/message.rb9
-rw-r--r--app/models/news.rb14
-rw-r--r--app/models/principal.rb16
-rw-r--r--app/models/project.rb66
-rw-r--r--app/models/query.rb20
-rw-r--r--app/models/repository.rb16
-rw-r--r--app/models/repository/cvs.rb2
-rw-r--r--app/models/repository/git.rb2
-rw-r--r--app/models/repository/mercurial.rb5
-rw-r--r--app/models/repository/subversion.rb2
-rw-r--r--app/models/role.rb2
-rw-r--r--app/models/setting.rb2
-rw-r--r--app/models/time_entry.rb14
-rw-r--r--app/models/time_entry_query.rb5
-rw-r--r--app/models/token.rb1
-rw-r--r--app/models/tracker.rb4
-rw-r--r--app/models/user.rb35
-rw-r--r--app/models/version.rb10
-rw-r--r--app/models/watcher.rb1
-rw-r--r--app/models/wiki.rb3
-rw-r--r--app/models/wiki_content.rb17
-rw-r--r--app/models/wiki_page.rb13
-rw-r--r--app/models/wiki_redirect.rb1
-rw-r--r--app/models/workflow_rule.rb3
-rw-r--r--app/models/workflow_transition.rb2
-rw-r--r--app/views/common/_tabs.html.erb4
-rw-r--r--app/views/groups/_memberships.html.erb2
-rw-r--r--app/views/projects/settings/_members.html.erb2
-rw-r--r--app/views/timelog/_form.html.erb2
-rw-r--r--app/views/users/_memberships.html.erb2
-rw-r--r--app/views/wiki/edit.html.erb2
-rw-r--r--app/views/wiki/rename.html.erb2
98 files changed, 434 insertions, 328 deletions
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index c2d464d42..b0e5ce6fa 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -34,7 +34,7 @@ class AdminController < ApplicationController
scope = Project.status(@status).order('lft')
scope = scope.like(params[:name]) if params[:name].present?
- @projects = scope.all
+ @projects = scope.to_a
render :action => "projects", :layout => false if request.xhr?
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index e8f3565ee..7fedd44ff 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -496,7 +496,7 @@ class ApplicationController < ActionController::Base
end
def render_feed(items, options={})
- @items = items || []
+ @items = (items || []).to_a
@items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
@items = @items.slice(0, Setting.feeds_limit.to_i)
@title = options[:title] || Setting.app_title
diff --git a/app/controllers/auto_completes_controller.rb b/app/controllers/auto_completes_controller.rb
index a48afdf90..991f0be16 100644
--- a/app/controllers/auto_completes_controller.rb
+++ b/app/controllers/auto_completes_controller.rb
@@ -26,7 +26,7 @@ class AutoCompletesController < ApplicationController
if q.match(/\A#?(\d+)\z/)
@issues << scope.find_by_id($1.to_i)
end
- @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).all
+ @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).to_a
@issues.compact!
end
render :layout => false
diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb
index 1f1d47342..04bdb56c0 100644
--- a/app/controllers/boards_controller.rb
+++ b/app/controllers/boards_controller.rb
@@ -25,7 +25,7 @@ class BoardsController < ApplicationController
helper :watchers
def index
- @boards = @project.boards.includes(:project, :last_message => :author).all
+ @boards = @project.boards.preload(:project, :last_message => :author).to_a
# show the board if there is only one
if @boards.size == 1
@board = @boards.first
@@ -45,12 +45,13 @@ class BoardsController < ApplicationController
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
@topics = @board.topics.
reorder("#{Message.table_name}.sticky DESC").
- includes(:last_reply).
+ joins("LEFT OUTER JOIN #{Message.table_name} last_replies_messages ON last_replies_messages.id = #{Message.table_name}.last_reply_id").
+ references(:last_reply).
limit(@topic_pages.per_page).
offset(@topic_pages.offset).
order(sort_clause).
preload(:author, {:last_reply => :author}).
- all
+ to_a
@message = Message.new(:board => @board)
render :action => 'show', :layout => !request.xhr?
}
@@ -59,7 +60,7 @@ class BoardsController < ApplicationController
reorder('created_on DESC').
includes(:author, :board).
limit(Setting.feeds_limit.to_i).
- all
+ to_a
render_feed(@messages, :title => "#{@project}: #{@board}")
}
end
diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb
index 43cfc2530..47065f934 100644
--- a/app/controllers/documents_controller.rb
+++ b/app/controllers/documents_controller.rb
@@ -27,7 +27,7 @@ class DocumentsController < ApplicationController
def index
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
- documents = @project.documents.includes(:attachments, :category).all
+ documents = @project.documents.includes(:attachments, :category).to_a
case @sort_by
when 'date'
@grouped = documents.group_by {|d| d.updated_on.to_date }
@@ -43,7 +43,7 @@ class DocumentsController < ApplicationController
end
def show
- @attachments = @document.attachments.all
+ @attachments = @document.attachments.to_a
end
def new
@@ -69,7 +69,7 @@ class DocumentsController < ApplicationController
def update
@document.safe_attributes = params[:document]
- if request.put? and @document.save
+ if @document.save
flash[:notice] = l(:notice_successful_update)
redirect_to document_path(@document)
else
diff --git a/app/controllers/enumerations_controller.rb b/app/controllers/enumerations_controller.rb
index 65a503974..d8d9141bb 100644
--- a/app/controllers/enumerations_controller.rb
+++ b/app/controllers/enumerations_controller.rb
@@ -32,7 +32,7 @@ class EnumerationsController < ApplicationController
format.api {
@klass = Enumeration.get_subclass(params[:type])
if @klass
- @enumerations = @klass.shared.sorted.all
+ @enumerations = @klass.shared.sorted.to_a
else
render_404
end
@@ -56,7 +56,7 @@ class EnumerationsController < ApplicationController
end
def update
- if request.put? && @enumeration.update_attributes(params[:enumeration])
+ if @enumeration.update_attributes(params[:enumeration])
flash[:notice] = l(:notice_successful_update)
redirect_to enumerations_path
else
@@ -75,7 +75,7 @@ class EnumerationsController < ApplicationController
redirect_to enumerations_path
return
end
- @enumerations = @enumeration.class.system.all - [@enumeration]
+ @enumerations = @enumeration.class.system.to_a - [@enumeration]
end
private
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index 6ba5c110c..f3eb6719f 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -31,8 +31,10 @@ class FilesController < ApplicationController
'size' => "#{Attachment.table_name}.filesize",
'downloads' => "#{Attachment.table_name}.downloads"
- @containers = [ Project.includes(:attachments).reorder(sort_clause).find(@project.id)]
- @containers += @project.versions.includes(:attachments).reorder(sort_clause).all.sort.reverse
+ @containers = [Project.includes(:attachments).
+ references(:attachments).reorder(sort_clause).find(@project.id)]
+ @containers += @project.versions.includes(:attachments).
+ references(:attachments).reorder(sort_clause).to_a.sort.reverse
render :layout => !request.xhr?
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 555fc61df..45ed4c4e1 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -27,13 +27,13 @@ class GroupsController < ApplicationController
def index
respond_to do |format|
format.html {
- @groups = Group.sorted.all
+ @groups = Group.sorted.to_a
@user_count_by_group_id = user_count_by_group_id
}
format.api {
scope = Group.sorted
scope = scope.givable unless params[:builtin] == '1'
- @groups = scope.all
+ @groups = scope.to_a
}
end
end
@@ -95,7 +95,7 @@ class GroupsController < ApplicationController
end
def add_users
- @users = User.where(:id => (params[:user_id] || params[:user_ids])).all
+ @users = User.where(:id => (params[:user_id] || params[:user_ids])).to_a
@group.users << @users if request.post?
respond_to do |format|
format.html { redirect_to edit_group_path(@group, :tab => 'users') }
diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb
index 6a956904a..3c73510ee 100644
--- a/app/controllers/issue_categories_controller.rb
+++ b/app/controllers/issue_categories_controller.rb
@@ -27,7 +27,7 @@ class IssueCategoriesController < ApplicationController
def index
respond_to do |format|
format.html { redirect_to_settings_in_projects }
- format.api { @categories = @project.issue_categories.all }
+ format.api { @categories = @project.issue_categories.to_a }
end
end
diff --git a/app/controllers/issue_statuses_controller.rb b/app/controllers/issue_statuses_controller.rb
index d305dedd7..a6b72f329 100644
--- a/app/controllers/issue_statuses_controller.rb
+++ b/app/controllers/issue_statuses_controller.rb
@@ -29,7 +29,7 @@ class IssueStatusesController < ApplicationController
render :action => "index", :layout => false if request.xhr?
}
format.api {
- @issue_statuses = IssueStatus.order('position').all
+ @issue_statuses = IssueStatus.order('position').to_a
}
end
end
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index de346c576..5623c3bfa 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -104,15 +104,16 @@ class IssuesController < ApplicationController
end
def show
- @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all
+ @journals = @issue.journals.includes(:user, :details).
+ references(:user, :details).
+ reorder("#{Journal.table_name}.id ASC").to_a
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
Journal.preload_journals_details_custom_fields(@journals)
- # TODO: use #select! when ruby1.8 support is dropped
- @journals.reject! {|journal| !journal.notes? && journal.visible_details.empty?}
+ @journals.select! {|journal| journal.notes? || journal.visible_details.any?}
@journals.reverse! if User.current.wants_comments_in_reverse_order?
- @changesets = @issue.changesets.visible.all
+ @changesets = @issue.changesets.visible.to_a
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
@@ -189,7 +190,7 @@ class IssuesController < ApplicationController
rescue ActiveRecord::StaleObjectError
@conflict = true
if params[:last_journal_id]
- @conflict_journals = @issue.journals_after(params[:last_journal_id]).all
+ @conflict_journals = @issue.journals_after(params[:last_journal_id]).to_a
@conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
end
end
@@ -301,7 +302,7 @@ class IssuesController < ApplicationController
else
@saved_issues = @issues
@unsaved_issues = unsaved_issues
- @issues = Issue.visible.where(:id => @unsaved_issues.map(&:id)).all
+ @issues = Issue.visible.where(:id => @unsaved_issues.map(&:id)).to_a
bulk_edit
render :action => 'bulk_edit'
end
@@ -375,7 +376,9 @@ class IssuesController < ApplicationController
def update_issue_from_params
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
- @time_entry.attributes = params[:time_entry]
+ if params[:time_entry]
+ @time_entry.attributes = params[:time_entry]
+ end
@issue.init_journal(User.current)
@@ -422,7 +425,9 @@ class IssuesController < ApplicationController
@issue.project = @project
@issue.author ||= User.current
# Tracker must be set before custom field values
- @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
+ tracker_id = (params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id]
+ tracker = tracker_id.present? ? @project.trackers.find(tracker_id) : @project.trackers.first
+ @issue.tracker ||= tracker
if @issue.tracker.nil?
render_error l(:error_no_tracker_in_project)
return false
diff --git a/app/controllers/journals_controller.rb b/app/controllers/journals_controller.rb
index fe1c01907..940a7b5e1 100644
--- a/app/controllers/journals_controller.rb
+++ b/app/controllers/journals_controller.rb
@@ -34,7 +34,6 @@ class JournalsController < ApplicationController
retrieve_query
sort_init 'id', 'desc'
sort_update(@query.sortable_columns)
-
if @query.valid?
@journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC",
:limit => 25)
diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb
index aca136754..ca5002af8 100644
--- a/app/controllers/members_controller.rb
+++ b/app/controllers/members_controller.rb
@@ -32,7 +32,7 @@ class MembersController < ApplicationController
order("#{Member.table_name}.id").
limit(@limit).
offset(@offset).
- all
+ to_a
respond_to do |format|
format.html { head 406 }
format.api
@@ -63,7 +63,10 @@ class MembersController < ApplicationController
respond_to do |format|
format.html { redirect_to_settings_in_projects }
- format.js { @members = members }
+ format.js {
+ @members = members
+ @member = Member.new
+ }
format.api {
@member = members.first
if @member.valid?
diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb
index 0eb9f0bef..aa0788a05 100644
--- a/app/controllers/messages_controller.rb
+++ b/app/controllers/messages_controller.rb
@@ -43,10 +43,10 @@ class MessagesController < ApplicationController
@reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page
@replies = @topic.children.
includes(:author, :attachments, {:board => :project}).
- reorder("#{Message.table_name}.created_on ASC").
+ reorder("#{Message.table_name}.created_on ASC, #{Message.table_name}.id ASC").
limit(@reply_pages.per_page).
offset(@reply_pages.offset).
- all
+ to_a
@reply = Message.new(:subject => "RE: #{@message.subject}")
render :action => "show", :layout => false if request.xhr?
diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb
index 714b23857..4fd18bab0 100644
--- a/app/controllers/my_controller.rb
+++ b/app/controllers/my_controller.rb
@@ -53,8 +53,8 @@ class MyController < ApplicationController
@user = User.current
@pref = @user.pref
if request.post?
- @user.safe_attributes = params[:user]
- @user.pref.attributes = params[:pref]
+ @user.safe_attributes = params[:user] if params[:user]
+ @user.pref.attributes = params[:pref] if params[:pref]
if @user.save
@user.pref.save
set_language_if_valid @user.language
diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb
index ffe662921..50c0489f4 100644
--- a/app/controllers/news_controller.rb
+++ b/app/controllers/news_controller.rb
@@ -46,7 +46,7 @@ class NewsController < ApplicationController
order("#{News.table_name}.created_on DESC").
limit(@limit).
offset(@offset).
- all
+ to_a
respond_to do |format|
format.html {
@news = News.new # for adding news inline
diff --git a/app/controllers/project_enumerations_controller.rb b/app/controllers/project_enumerations_controller.rb
index 2475dbf65..df4fcbf23 100644
--- a/app/controllers/project_enumerations_controller.rb
+++ b/app/controllers/project_enumerations_controller.rb
@@ -20,7 +20,7 @@ class ProjectEnumerationsController < ApplicationController
before_filter :authorize
def update
- if request.put? && params[:enumerations]
+ if params[:enumerations]
Project.transaction do
params[:enumerations].each do |id, activity|
@project.update_or_create_time_entry_activity(id, activity)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 1225f2f01..0a6b487a8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -53,30 +53,30 @@ class ProjectsController < ApplicationController
unless params[:closed]
scope = scope.active
end
- @projects = scope.visible.order('lft').all
+ @projects = scope.visible.order('lft').to_a
}
format.api {
@offset, @limit = api_offset_and_limit
@project_count = Project.visible.count
- @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
+ @projects = Project.visible.offset(@offset).limit(@limit).order('lft').to_a
}
format.atom {
- projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all
+ projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).to_a
render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
}
end
end
def new
- @issue_custom_fields = IssueCustomField.sorted.all
- @trackers = Tracker.sorted.all
+ @issue_custom_fields = IssueCustomField.sorted.to_a
+ @trackers = Tracker.sorted.to_a
@project = Project.new
@project.safe_attributes = params[:project]
end
def create
- @issue_custom_fields = IssueCustomField.sorted.all
- @trackers = Tracker.sorted.all
+ @issue_custom_fields = IssueCustomField.sorted.to_a
+ @trackers = Tracker.sorted.to_a
@project = Project.new
@project.safe_attributes = params[:project]
@@ -109,8 +109,8 @@ class ProjectsController < ApplicationController
end
def copy
- @issue_custom_fields = IssueCustomField.sorted.all
- @trackers = Tracker.sorted.all
+ @issue_custom_fields = IssueCustomField.sorted.to_a
+ @trackers = Tracker.sorted.to_a
@source_project = Project.find(params[:id])
if request.get?
@project = Project.copy_from(@source_project)
@@ -145,8 +145,8 @@ class ProjectsController < ApplicationController
end
@users_by_role = @project.users_by_role
- @subprojects = @project.children.visible.all
- @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all
+ @subprojects = @project.children.visible.to_a
+ @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a
@trackers = @project.rolled_up_trackers
cond = @project.project_condition(Setting.display_subprojects_issues?)
@@ -167,10 +167,10 @@ class ProjectsController < ApplicationController
end
def settings
- @issue_custom_fields = IssueCustomField.sorted.all
+ @issue_custom_fields = IssueCustomField.sorted.to_a
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
@wiki ||= @project.wiki
end
diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb
index 049e3534b..22ec9e929 100644
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -37,8 +37,9 @@ class QueriesController < ApplicationController
order("#{Query.table_name}.name").
limit(@limit).
offset(@offset).
- all
+ to_a
respond_to do |format|
+ format.html {render_error :status => 406}
format.api
end
end
diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb
index 00c94a106..43dac3673 100644
--- a/app/controllers/reports_controller.rb
+++ b/app/controllers/reports_controller.rb
@@ -90,6 +90,6 @@ class ReportsController < ApplicationController
private
def find_issue_statuses
- @statuses = IssueStatus.sorted.all
+ @statuses = IssueStatus.sorted.to_a
end
end
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 59afc5529..7eb72865b 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -69,7 +69,7 @@ class RepositoriesController < ApplicationController
@repository.merge_extra_info(attrs[:attrs_extra])
end
@repository.project = @project
- if request.put? && @repository.save
+ if @repository.save
redirect_to settings_project_path(@project, :tab => 'repositories')
else
render :action => 'edit'
@@ -94,7 +94,7 @@ class RepositoriesController < ApplicationController
@committers = @repository.committers
@users = @project.users
additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
- @users += User.where(:id => additional_user_ids).all unless additional_user_ids.empty?
+ @users += User.where(:id => additional_user_ids).to_a unless additional_user_ids.empty?
@users.compact!
@users.sort!
if request.post? && params[:committers].is_a?(Hash)
@@ -145,7 +145,7 @@ class RepositoriesController < ApplicationController
limit(@changeset_pages.per_page).
offset(@changeset_pages.offset).
includes(:user, :repository, :parents).
- all
+ to_a
respond_to do |format|
format.html { render :layout => false if request.xhr? }
diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb
index 8a976779e..a74d8bb91 100644
--- a/app/controllers/roles_controller.rb
+++ b/app/controllers/roles_controller.rb
@@ -30,7 +30,7 @@ class RolesController < ApplicationController
render :action => "index", :layout => false if request.xhr?
}
format.api {
- @roles = Role.givable.all
+ @roles = Role.givable.to_a
}
end
end
@@ -47,7 +47,7 @@ class RolesController < ApplicationController
if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
@role.copy_from(@copy_from)
end
- @roles = Role.sorted.all
+ @roles = Role.sorted.to_a
end
def create
@@ -60,7 +60,7 @@ class RolesController < ApplicationController
flash[:notice] = l(:notice_successful_create)
redirect_to roles_path
else
- @roles = Role.sorted.all
+ @roles = Role.sorted.to_a
render :action => 'new'
end
end
@@ -69,7 +69,7 @@ class RolesController < ApplicationController
end
def update
- if request.put? and @role.update_attributes(params[:role])
+ if @role.update_attributes(params[:role])
flash[:notice] = l(:notice_successful_update)
redirect_to roles_path
else
@@ -86,7 +86,7 @@ class RolesController < ApplicationController
end
def permissions
- @roles = Role.sorted.all
+ @roles = Role.sorted.to_a
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
if request.post?
@roles.each do |role|
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index afc756677..ec8b4812c 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -31,7 +31,7 @@ class SearchController < ApplicationController
when 'my_projects'
User.current.memberships.collect(&:project)
when 'subprojects'
- @project ? (@project.self_and_descendants.active.all) : nil
+ @project ? (@project.self_and_descendants.active.to_a) : nil
else
@project
end
diff --git a/app/controllers/sys_controller.rb b/app/controllers/sys_controller.rb
index d8ef783eb..0b62b420c 100644
--- a/app/controllers/sys_controller.rb
+++ b/app/controllers/sys_controller.rb
@@ -19,7 +19,8 @@ class SysController < ActionController::Base
before_filter :check_enabled
def projects
- p = Project.active.has_module(:repository).order("#{Project.table_name}.identifier").preload(:repository).all
+ p = Project.active.has_module(:repository).
+ order("#{Project.table_name}.identifier").preload(:repository).to_a
# extra_info attribute from repository breaks activeresource client
render :xml => p.to_xml(
:only => [:id, :identifier, :name, :is_public, :status],
@@ -56,7 +57,7 @@ class SysController < ActionController::Base
raise ActiveRecord::RecordNotFound unless project
projects << project
else
- projects = scope.all
+ projects = scope.to_a
end
projects.each do |project|
project.repositories.each do |repository|
diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb
index 13923b1e5..20eccef71 100644
--- a/app/controllers/timelog_controller.rb
+++ b/app/controllers/timelog_controller.rb
@@ -52,7 +52,7 @@ class TimelogController < ApplicationController
format.html {
@entry_count = scope.count
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
- @entries = scope.offset(@entry_pages.offset).limit(@entry_pages.per_page).all
+ @entries = scope.offset(@entry_pages.offset).limit(@entry_pages.per_page).to_a
@total_hours = scope.sum(:hours).to_f
render :layout => !request.xhr?
@@ -60,15 +60,15 @@ class TimelogController < ApplicationController
format.api {
@entry_count = scope.count
@offset, @limit = api_offset_and_limit
- @entries = scope.offset(@offset).limit(@limit).preload(:custom_values => :custom_field).all
+ @entries = scope.offset(@offset).limit(@limit).preload(:custom_values => :custom_field).to_a
}
format.atom {
- entries = scope.limit(Setting.feeds_limit.to_i).reorder("#{TimeEntry.table_name}.created_on DESC").all
+ entries = scope.limit(Setting.feeds_limit.to_i).reorder("#{TimeEntry.table_name}.created_on DESC").to_a
render_feed(entries, :title => l(:label_spent_time))
}
format.csv {
# Export all entries
- @entries = scope.all
+ @entries = scope.to_a
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
}
end
@@ -232,7 +232,7 @@ private
end
def find_time_entries
- @time_entries = TimeEntry.where(:id => params[:id] || params[:ids]).all
+ @time_entries = TimeEntry.where(:id => params[:id] || params[:ids]).to_a
raise ActiveRecord::RecordNotFound if @time_entries.empty?
@projects = @time_entries.collect(&:project).compact.uniq
@project = @projects.first if @projects.size == 1
diff --git a/app/controllers/trackers_controller.rb b/app/controllers/trackers_controller.rb
index 02274d0d3..ec0b9ce3f 100644
--- a/app/controllers/trackers_controller.rb
+++ b/app/controllers/trackers_controller.rb
@@ -29,14 +29,14 @@ class TrackersController < ApplicationController
render :action => "index", :layout => false if request.xhr?
}
format.api {
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
}
end
end
def new
@tracker ||= Tracker.new(params[:tracker])
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
@projects = Project.all
end
@@ -95,7 +95,7 @@ class TrackersController < ApplicationController
redirect_to fields_trackers_path
return
end
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
@custom_fields = IssueCustomField.all.sort
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index c5db58988..bb56fb285 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -47,7 +47,7 @@ class UsersController < ApplicationController
@user_count = scope.count
@user_pages = Paginator.new @user_count, @limit, params['page']
@offset ||= @user_pages.offset
- @users = scope.order(sort_clause).limit(@limit).offset(@offset).all
+ @users = scope.order(sort_clause).limit(@limit).offset(@offset).to_a
respond_to do |format|
format.html {
@@ -60,7 +60,7 @@ class UsersController < ApplicationController
def show
# show projects based on current user visibility
- @memberships = @user.memberships.where(Project.visible_condition(User.current)).all
+ @memberships = @user.memberships.where(Project.visible_condition(User.current)).to_a
events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
@events_by_day = events.group_by(&:event_date)
@@ -90,7 +90,7 @@ class UsersController < ApplicationController
@user.admin = params[:user][:admin] || false
@user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id
- @user.pref.attributes = params[:pref]
+ @user.pref.attributes = params[:pref] if params[:pref]
if @user.save
Mailer.account_information(@user, @user.password).deliver if params[:send_information]
@@ -134,7 +134,7 @@ class UsersController < ApplicationController
# Was the account actived ? (do it before User#save clears the change)
was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
# TODO: Similar to My#account
- @user.pref.attributes = params[:pref]
+ @user.pref.attributes = params[:pref] if params[:pref]
if @user.save
@user.pref.save
diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb
index a49f8a09a..bf2315321 100644
--- a/app/controllers/versions_controller.rb
+++ b/app/controllers/versions_controller.rb
@@ -31,7 +31,7 @@ class VersionsController < ApplicationController
def index
respond_to do |format|
format.html {
- @trackers = @project.trackers.sorted.all
+ @trackers = @project.trackers.sorted.to_a
retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
@@ -56,7 +56,7 @@ class VersionsController < ApplicationController
@versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
}
format.api {
- @versions = @project.shared_versions.all
+ @versions = @project.shared_versions.to_a
}
end
end
@@ -67,7 +67,7 @@ class VersionsController < ApplicationController
@issues = @version.fixed_issues.visible.
includes(:status, :tracker, :priority).
reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
- all
+ to_a
}
format.api
end
@@ -117,7 +117,7 @@ class VersionsController < ApplicationController
end
def update
- if request.put? && params[:version]
+ if params[:version]
attributes = params[:version].dup
attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
@version.safe_attributes = attributes
diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb
index e6c4d3119..ade977b41 100644
--- a/app/controllers/watchers_controller.rb
+++ b/app/controllers/watchers_controller.rb
@@ -53,7 +53,7 @@ class WatchersController < ApplicationController
def append
if params[:watcher].is_a?(Hash)
user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
- @users = User.active.where(:id => user_ids).all
+ @users = User.active.where(:id => user_ids).to_a
end
if @users.blank?
render :nothing => true
@@ -92,7 +92,7 @@ class WatchersController < ApplicationController
def find_watchables
klass = Object.const_get(params[:object_type].camelcase) rescue nil
if klass && klass.respond_to?('watched_by')
- @watchables = klass.where(:id => Array.wrap(params[:object_id])).all
+ @watchables = klass.where(:id => Array.wrap(params[:object_id])).to_a
raise Unauthorized if @watchables.any? {|w|
if w.respond_to?(:visible?)
!w.visible?
diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb
index 723c7191d..9b3981655 100644
--- a/app/controllers/wiki_controller.rb
+++ b/app/controllers/wiki_controller.rb
@@ -219,7 +219,7 @@ class WikiController < ApplicationController
reorder('version DESC').
limit(@version_pages.per_page + 1).
offset(@version_pages.offset).
- all
+ to_a
render :layout => false if request.xhr?
end
@@ -280,7 +280,7 @@ class WikiController < ApplicationController
@pages = @wiki.pages.
order('title').
includes([:content, {:attachments => :author}]).
- all
+ to_a
respond_to do |format|
format.html {
export = render_to_string :action => 'export_multiple', :layout => false
@@ -327,7 +327,7 @@ private
def find_existing_or_new_page
@page = @wiki.find_or_new_page(params[:id])
if @wiki.page_found_with_redirect?
- redirect_to params.update(:id => @page.title)
+ redirect_to_page @page
end
end
@@ -339,10 +339,14 @@ private
return
end
if @wiki.page_found_with_redirect?
- redirect_to params.update(:id => @page.title)
+ redirect_to_page @page
end
end
+ def redirect_to_page(page)
+ redirect_to :action => action_name, :project_id => page.wiki.project, :id => page.title
+ end
+
# Returns true if the current user is allowed to edit the page, otherwise false
def editable?(page = @page)
page.editable_by?(User.current)
@@ -360,6 +364,6 @@ private
reorder("#{WikiPage.table_name}.title").
includes(:wiki => :project).
includes(:parent).
- all
+ to_a
end
end
diff --git a/app/controllers/workflows_controller.rb b/app/controllers/workflows_controller.rb
index fd700d25e..28b0f2242 100644
--- a/app/controllers/workflows_controller.rb
+++ b/app/controllers/workflows_controller.rb
@@ -86,9 +86,9 @@ class WorkflowsController < ApplicationController
@source_role = Role.find_by_id(params[:source_role_id].to_i)
end
@target_trackers = params[:target_tracker_ids].blank? ?
- nil : Tracker.where(:id => params[:target_tracker_ids]).all
+ nil : Tracker.where(:id => params[:target_tracker_ids]).to_a
@target_roles = params[:target_role_ids].blank? ?
- nil : Role.where(:id => params[:target_role_ids]).all
+ nil : Role.where(:id => params[:target_role_ids]).to_a
if request.post?
if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
flash.now[:error] = l(:error_workflow_copy_source)
@@ -113,9 +113,9 @@ class WorkflowsController < ApplicationController
def find_roles
ids = Array.wrap(params[:role_id])
if ids == ['all']
- @roles = Role.sorted.all
+ @roles = Role.sorted.to_a
elsif ids.present?
- @roles = Role.where(:id => ids).all
+ @roles = Role.where(:id => ids).to_a
end
@roles = nil if @roles.blank?
end
@@ -123,9 +123,9 @@ class WorkflowsController < ApplicationController
def find_trackers
ids = Array.wrap(params[:tracker_id])
if ids == ['all']
- @trackers = Tracker.sorted.all
+ @trackers = Tracker.sorted.to_a
elsif ids.present?
- @trackers = Tracker.where(:id => ids).all
+ @trackers = Tracker.where(:id => ids).to_a
end
@trackers = nil if @trackers.blank?
end
@@ -135,6 +135,6 @@ class WorkflowsController < ApplicationController
if @trackers && @used_statuses_only
@statuses = @trackers.map(&:issue_statuses).flatten.uniq.sort.presence
end
- @statuses ||= IssueStatus.sorted.all
+ @statuses ||= IssueStatus.sorted.to_a
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 6b5dd08e0..0cb4c4c00 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -138,9 +138,7 @@ module ApplicationHelper
if project.archived?
h(project.name)
elsif options.key?(:action)
- ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0."
- url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
- link_to project.name, url, html_options
+ raise "#link_to_project no longer accepts :action option in Redmine 3.0"
else
link_to project.name, project_path(project, options), html_options
end
@@ -157,13 +155,6 @@ module ApplicationHelper
end
end
- # Generates a link to a version
- def link_to_version(version, options = {})
- return '' unless version && version.is_a?(Version)
- options = {:title => format_date(version.effective_date)}.merge(options)
- link_to_if version.visible?, format_version_name(version), version_path(version), options
- end
-
# Helper that formats object for html or text rendering
def format_object(object, html=true, &block)
if block_given?
@@ -185,7 +176,7 @@ module ApplicationHelper
when 'Project'
html ? link_to_project(object) : object.to_s
when 'Version'
- html ? link_to_version(object) : object.to_s
+ html ? link_to(object.name, version_path(object)) : object.to_s
when 'TrueClass'
l(:general_text_Yes)
when 'FalseClass'
@@ -247,7 +238,7 @@ module ApplicationHelper
end
def format_version_name(version)
- if !version.shared? || version.project == @project
+ if version.project == @project
h(version)
else
h("#{version.project} - #{version}")
@@ -502,7 +493,7 @@ module ApplicationHelper
h(Setting.app_title)
else
b = []
- ancestors = (@project.root? ? [] : @project.ancestors.visible.all)
+ ancestors = (@project.root? ? [] : @project.ancestors.visible.to_a)
if ancestors.any?
root = ancestors.shift
b << link_to_project(root, {:jump => current_menu_item}, :class => 'root')
@@ -1217,7 +1208,7 @@ module ApplicationHelper
source
end
end
- super sources, options
+ super *sources, options
end
# Overrides Rails' image_tag with themes and plugins support.
@@ -1250,7 +1241,7 @@ module ApplicationHelper
end
end
end
- super sources, options
+ super *sources, options
end
# TODO: remove this in 2.5.0
@@ -1288,12 +1279,7 @@ module ApplicationHelper
end
def sanitize_anchor_name(anchor)
- if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java'
- anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
- else
- # TODO: remove when ruby1.8 is no longer supported
- anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
- end
+ anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
end
# Returns the javascript tags that are included in the html layout head
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 4777328b0..315be99fc 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -30,7 +30,7 @@ module GroupsHelper
scope = User.active.sorted.not_in_group(group).like(params[:q])
principal_count = scope.count
principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
- principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+ principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).to_a
s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 8d7f9641c..9760a8ebb 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -63,7 +63,7 @@ module IssuesHelper
def render_issue_subject_with_tree(issue)
s = ''
- ancestors = issue.root? ? [] : issue.ancestors.visible.all
+ ancestors = issue.root? ? [] : issue.ancestors.visible.to_a
ancestors.each do |ancestor|
s << '<div>' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id)))
end
@@ -204,7 +204,7 @@ module IssuesHelper
order("#{Query.table_name}.name ASC").
# Project specific queries and global queries
where(@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]).
- all
+ to_a
end
@sidebar_queries
end
@@ -408,7 +408,7 @@ module IssuesHelper
if association
record = association.class_name.constantize.find_by_id(id)
if record
- record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding)
+ record.name.force_encoding('UTF-8')
return record.name
end
end
diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb
index 5e98643db..4aae46475 100644
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -22,7 +22,7 @@ module MembersHelper
scope = Principal.active.sorted.not_member_of(project).like(params[:q])
principal_count = scope.count
principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
- principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+ principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).to_a
s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
diff --git a/app/helpers/my_helper.rb b/app/helpers/my_helper.rb
index 8e78dfbe9..5917f26ec 100644
--- a/app/helpers/my_helper.rb
+++ b/app/helpers/my_helper.rb
@@ -23,11 +23,12 @@ module MyHelper
where(:project_id => User.current.projects.map(&:id)).
where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt).
includes(:project, :tracker, :priority, :assigned_to).
- all
+ references(:project, :tracker, :priority, :assigned_to).
+ to_a
end
def documents_items
- Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all
+ Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).to_a
end
def issuesassignedtome_items
@@ -35,8 +36,9 @@ module MyHelper
where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
limit(10).
includes(:status, :project, :tracker, :priority).
+ references(:status, :project, :tracker, :priority).
order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
- all
+ to_a
end
def issuesreportedbyme_items
@@ -44,12 +46,13 @@ module MyHelper
where(:author_id => User.current.id).
limit(10).
includes(:status, :project, :tracker).
+ references(:status, :project, :tracker).
order("#{Issue.table_name}.updated_on DESC").
- all
+ to_a
end
def issueswatched_items
- Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all
+ Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).to_a
end
def news_items
@@ -57,15 +60,17 @@ module MyHelper
where(:project_id => User.current.projects.map(&:id)).
limit(10).
includes(:project, :author).
+ references(:project, :author).
order("#{News.table_name}.created_on DESC").
- all
+ to_a
end
def timelog_items
TimeEntry.
where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today).
- includes(:activity, :project, {:issue => [:tracker, :status]}).
+ joins(:activity, :project, {:issue => [:tracker, :status]}).
+ references(:activity, :project, {:issue => [:tracker, :status]}).
order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
- all
+ to_a
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 8e23ccdda..e23ebab99 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -18,6 +18,11 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module ProjectsHelper
+ def link_to_version(version, options = {})
+ return '' unless version && version.is_a?(Version)
+ link_to_if version.visible?, format_version_name(version), version_path(version), options
+ end
+
def project_settings_tabs
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
{:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb
index ca8d2537b..0206b160a 100644
--- a/app/helpers/queries_helper.rb
+++ b/app/helpers/queries_helper.rb
@@ -143,7 +143,7 @@ module QueriesHelper
end
end
- export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
+ export = CSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
# csv header fields
csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
# csv lines
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index a39686b3d..15433750a 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -29,7 +29,6 @@ module SearchHelper
result << '...'
break
end
- words = words.mb_chars
if i.even?
result << h(words.length > 100 ? "#{words.slice(0..44)} ... #{words.slice(-45..-1)}" : words)
else
diff --git a/app/helpers/sort_helper.rb b/app/helpers/sort_helper.rb
index cbdc41883..da74aeac2 100644
--- a/app/helpers/sort_helper.rb
+++ b/app/helpers/sort_helper.rb
@@ -84,7 +84,8 @@ module SortHelper
def to_sql
sql = @criteria.collect do |k,o|
if s = @available_criteria[k]
- (o ? s.to_a : s.to_a.collect {|c| append_desc(c)})
+ s = [s] unless s.is_a?(Array)
+ (o ? s : s.collect {|c| append_desc(c)})
end
end.flatten.compact
sql.blank? ? nil : sql
diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb
index 02532c3f1..c68d2c0c5 100644
--- a/app/helpers/timelog_helper.rb
+++ b/app/helpers/timelog_helper.rb
@@ -105,7 +105,7 @@ module TimelogHelper
def report_to_csv(report)
decimal_separator = l(:general_csv_decimal_separator)
- export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
+ export = CSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
# Column headers
headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
headers += report.periods
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index f36f7cccf..9d7e03247 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -27,6 +27,7 @@ class Attachment < ActiveRecord::Base
validates_length_of :disk_filename, :maximum => 255
validates_length_of :description, :maximum => 255
validate :validate_max_file_size
+ attr_protected :id
acts_as_event :title => :filename,
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
@@ -34,16 +35,16 @@ class Attachment < ActiveRecord::Base
acts_as_activity_provider :type => 'files',
:permission => :view_files,
:author_key => :author_id,
- :find_options => {:select => "#{Attachment.table_name}.*",
- :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
- "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"}
+ :scope => select("#{Attachment.table_name}.*").
+ joins("LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
+ "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )")
acts_as_activity_provider :type => 'documents',
:permission => :view_documents,
:author_key => :author_id,
- :find_options => {:select => "#{Attachment.table_name}.*",
- :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
- "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
+ :scope => select("#{Attachment.table_name}.*").
+ joins("LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
+ "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id")
cattr_accessor :storage_path
@@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files")
@@ -74,7 +75,7 @@ class Attachment < ActiveRecord::Base
if @temp_file.size > 0
if @temp_file.respond_to?(:original_filename)
self.filename = @temp_file.original_filename
- self.filename.force_encoding("UTF-8") if filename.respond_to?(:force_encoding)
+ self.filename.force_encoding("UTF-8")
end
if @temp_file.respond_to?(:content_type)
self.content_type = @temp_file.content_type.to_s.chomp
diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb
index 1494e161a..aa2506e5b 100644
--- a/app/models/auth_source.rb
+++ b/app/models/auth_source.rb
@@ -29,6 +29,7 @@ class AuthSource < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :maximum => 60
+ attr_protected :id
def authenticate(login, password)
end
diff --git a/app/models/board.rb b/app/models/board.rb
index 387792cb4..2cbeb0a8a 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -18,8 +18,8 @@
class Board < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
- has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
- has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
+ has_many :topics, lambda {where("#{Message.table_name}.parent_id IS NULL").order("#{Message.table_name}.created_on DESC")}, :class_name => 'Message'
+ has_many :messages, lambda {order("#{Message.table_name}.created_on DESC")}, :dependent => :destroy
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
acts_as_tree :dependent => :nullify
acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})'
@@ -29,9 +29,12 @@ class Board < ActiveRecord::Base
validates_length_of :name, :maximum => 30
validates_length_of :description, :maximum => 255
validate :validate_board
+ attr_protected :id
scope :visible, lambda {|*args|
- includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+ joins(:project).
+ references(:project).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
}
safe_attributes 'name', 'description', 'parent_id', 'move_to'
diff --git a/app/models/change.rb b/app/models/change.rb
index 6ef56e0de..b24c1bd54 100644
--- a/app/models/change.rb
+++ b/app/models/change.rb
@@ -21,6 +21,7 @@ class Change < ActiveRecord::Base
validates_presence_of :changeset_id, :action, :path
before_save :init_path
before_validation :replace_invalid_utf8_of_path
+ attr_protected :id
def relative_path
changeset.repository.relative_path(path)
diff --git a/app/models/changeset.rb b/app/models/changeset.rb
index cf58c6e07..b12ea6778 100644
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -35,20 +35,23 @@ class Changeset < ActiveRecord::Base
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}}
acts_as_searchable :columns => 'comments',
- :include => {:repository => :project},
+ :scope => preload(:repository => :project),
:project_key => "#{Repository.table_name}.project_id",
:date_column => 'committed_on'
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
:author_key => :user_id,
- :find_options => {:include => [:user, {:repository => :project}]}
+ :scope => preload(:user, {:repository => :project})
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
validates_uniqueness_of :revision, :scope => :repository_id
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
+ attr_protected :id
scope :visible, lambda {|*args|
- includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
+ joins(:repository => :project).
+ references(:repository => :project).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
}
after_create :scan_for_issues
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 02d9a3b36..9893ad664 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -21,6 +21,7 @@ class Comment < ActiveRecord::Base
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :commented, :author, :comments
+ attr_protected :id
after_create :send_notification
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index 48ef2c7cc..f3829bf70 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -29,6 +29,7 @@ class CustomField < ActiveRecord::Base
validates_length_of :name, :maximum => 30
validates_inclusion_of :field_format, :in => Proc.new { Redmine::FieldFormat.available_formats }
validate :validate_custom_field
+ attr_protected :id
before_validation :set_searchable
before_save do |field|
@@ -117,7 +118,7 @@ class CustomField < ActiveRecord::Base
values = read_attribute(:possible_values)
if values.is_a?(Array)
values.each do |value|
- value.force_encoding('UTF-8') if value.respond_to?(:force_encoding)
+ value.force_encoding('UTF-8')
end
values
else
@@ -218,7 +219,7 @@ class CustomField < ActiveRecord::Base
# to move in project_custom_field
def self.for_all
- where(:is_for_all => true).order('position').all
+ where(:is_for_all => true).order('position').to_a
end
def type_name
diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb
index 952646311..ab2eee744 100644
--- a/app/models/custom_value.rb
+++ b/app/models/custom_value.rb
@@ -18,6 +18,7 @@
class CustomValue < ActiveRecord::Base
belongs_to :custom_field
belongs_to :customized, :polymorphic => true
+ attr_protected :id
def initialize(attributes=nil, *args)
super
diff --git a/app/models/document.rb b/app/models/document.rb
index 4609d8602..c195f64ca 100644
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -21,19 +21,23 @@ class Document < ActiveRecord::Base
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
acts_as_attachable :delete_permission => :delete_documents
- acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
+ acts_as_searchable :columns => ['title', "#{table_name}.description"],
+ :scope => preload(:project)
acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
:author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) },
:url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
- acts_as_activity_provider :find_options => {:include => :project}
+ acts_as_activity_provider :scope => preload(:project)
validates_presence_of :project, :title, :category
validates_length_of :title, :maximum => 60
+ attr_protected :id
after_create :send_notification
scope :visible, lambda {|*args|
- includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args))
+ joins(:project).
+ references(:project).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args))
}
safe_attributes 'category_id', 'title', 'description'
diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb
index 1cc84aaa5..baf6cdd11 100644
--- a/app/models/enabled_module.rb
+++ b/app/models/enabled_module.rb
@@ -21,6 +21,7 @@ class EnabledModule < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => :project_id
+ attr_protected :id
after_create :module_enabled
diff --git a/app/models/enumeration.rb b/app/models/enumeration.rb
index b4b64b7fc..8c82a0dc8 100644
--- a/app/models/enumeration.rb
+++ b/app/models/enumeration.rb
@@ -18,7 +18,7 @@
class Enumeration < ActiveRecord::Base
include Redmine::SubclassFactory
- default_scope :order => "#{Enumeration.table_name}.position ASC"
+ default_scope lambda {order("#{Enumeration.table_name}.position ASC")}
belongs_to :project
diff --git a/app/models/group.rb b/app/models/group.rb
index 7b82d1c1f..b9d4d9ef4 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -28,6 +28,7 @@ class Group < Principal
validates_presence_of :lastname
validates_uniqueness_of :lastname, :case_sensitive => false
validates_length_of :lastname, :maximum => 255
+ attr_protected :id
before_destroy :remove_references_before_destroy
@@ -81,7 +82,8 @@ class Group < Principal
def user_removed(user)
members.each do |member|
MemberRole.
- includes(:member).
+ joins(:member).
+ references(:member).
where("#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids).
each(&:destroy)
end
@@ -95,10 +97,6 @@ class Group < Principal
super(attr_name, *args)
end
- def self.builtin_id(arg)
- (arg.anonymous? ? GroupAnonymous : GroupNonMember).instance_id
- end
-
def self.anonymous
GroupAnonymous.load_instance
end
diff --git a/app/models/group_anonymous.rb b/app/models/group_anonymous.rb
index c3c821bb2..a6d01853d 100644
--- a/app/models/group_anonymous.rb
+++ b/app/models/group_anonymous.rb
@@ -23,8 +23,4 @@ class GroupAnonymous < GroupBuiltin
def builtin_type
"anonymous"
end
-
- def self.instance_id
- @@instance_id ||= load_instance.id
- end
end
diff --git a/app/models/group_builtin.rb b/app/models/group_builtin.rb
index 71ecc06ab..538a89eea 100644
--- a/app/models/group_builtin.rb
+++ b/app/models/group_builtin.rb
@@ -37,7 +37,7 @@ class GroupBuiltin < Group
class << self
def load_instance
return nil if self == GroupBuiltin
- instance = first(:order => 'id') || create_instance
+ instance = order('id').first || create_instance
end
def create_instance
diff --git a/app/models/group_non_member.rb b/app/models/group_non_member.rb
index 8b3dfd4aa..9f78f0b46 100644
--- a/app/models/group_non_member.rb
+++ b/app/models/group_non_member.rb
@@ -23,8 +23,4 @@ class GroupNonMember < GroupBuiltin
def builtin_type
"non_member"
end
-
- def self.instance_id
- @@instance_id ||= load_instance.id
- end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 1c1c99dec..bb45a6f58 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -31,15 +31,12 @@ class Issue < ActiveRecord::Base
has_many :journals, :as => :journalized, :dependent => :destroy
has_many :visible_journals,
+ lambda {where(["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false])},
:class_name => 'Journal',
- :as => :journalized,
- :conditions => Proc.new {
- ["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false]
- },
- :readonly => true
+ :as => :journalized
has_many :time_entries, :dependent => :destroy
- has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC"
+ has_and_belongs_to_many :changesets, lambda {order("#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC")}
has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
@@ -49,14 +46,19 @@ class Issue < ActiveRecord::Base
acts_as_customizable
acts_as_watchable
acts_as_searchable :columns => ['subject', "#{table_name}.description", "#{Journal.table_name}.notes"],
- :include => [:project, :visible_journals],
# sort by id so that limited eager loading doesn't break with postgresql
- :order_column => "#{table_name}.id"
+ :order_column => "#{table_name}.id",
+ :scope => lambda { joins(:project).
+ joins("LEFT OUTER JOIN #{Journal.table_name} ON #{Journal.table_name}.journalized_type='Issue'" +
+ " AND #{Journal.table_name}.journalized_id = #{Issue.table_name}.id" +
+ " AND (#{Journal.table_name}.private_notes = #{connection.quoted_false}" +
+ " OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))") }
+
acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.status}): #{o.subject}"},
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}},
:type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') }
- acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
+ acts_as_activity_provider :scope => preload(:project, :author, :tracker),
:author_key => :author_id
DONE_RATIO_OPTIONS = %w(issue_field issue_status)
@@ -72,19 +74,26 @@ class Issue < ActiveRecord::Base
validates :start_date, :date => true
validates :due_date, :date => true
validate :validate_issue, :validate_required_fields
+ attr_protected :id
scope :visible, lambda {|*args|
- includes(:project).where(Issue.visible_condition(args.shift || User.current, *args))
+ joins(:project).
+ references(:project).
+ where(Issue.visible_condition(args.shift || User.current, *args))
}
scope :open, lambda {|*args|
is_closed = args.size > 0 ? !args.first : false
- includes(:status).where("#{IssueStatus.table_name}.is_closed = ?", is_closed)
+ joins(:status).
+ references(:status).
+ where("#{IssueStatus.table_name}.is_closed = ?", is_closed)
}
scope :recently_updated, lambda { order("#{Issue.table_name}.updated_on DESC") }
scope :on_active_project, lambda {
- includes(:status, :project, :tracker).where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE)
+ joins(:project).
+ references(:project).
+ where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE)
}
scope :fixed_version, lambda {|versions|
ids = [versions].flatten.compact.map {|v| v.is_a?(Version) ? v.id : v}
@@ -107,7 +116,7 @@ class Issue < ActiveRecord::Base
# Returns a SQL conditions string used to find all issues visible by the specified user
def self.visible_condition(user, options={})
Project.allowed_to_condition(user, :view_issues, options) do |role, user|
- if user.logged?
+ if user.id && user.logged?
case role.issues_visibility
when 'all'
nil
@@ -351,6 +360,10 @@ class Issue < ActiveRecord::Base
# Do not redefine alias chain on reload (see #4838)
alias_method_chain(:assign_attributes, :project_and_tracker_first) unless method_defined?(:assign_attributes_without_project_and_tracker_first)
+ def attributes=(new_attributes)
+ assign_attributes new_attributes
+ end
+
def estimated_hours=(h)
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
end
@@ -423,7 +436,7 @@ class Issue < ActiveRecord::Base
def safe_attributes=(attrs, user=User.current)
return unless attrs.is_a?(Hash)
- attrs = attrs.dup
+ attrs = attrs.deep_dup
# Project and Tracker must be set before since new_statuses_allowed_to depends on it.
if (p = attrs.delete('project_id')) && safe_attribute?('project_id')
@@ -458,14 +471,12 @@ class Issue < ActiveRecord::Base
if attrs['custom_field_values'].present?
editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
- # TODO: use #select when ruby1.8 support is dropped
- attrs['custom_field_values'] = attrs['custom_field_values'].reject {|k, v| !editable_custom_field_ids.include?(k.to_s)}
+ attrs['custom_field_values'].select! {|k, v| editable_custom_field_ids.include?(k.to_s)}
end
if attrs['custom_fields'].present?
editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
- # TODO: use #select when ruby1.8 support is dropped
- attrs['custom_fields'] = attrs['custom_fields'].reject {|c| !editable_custom_field_ids.include?(c['id'].to_s)}
+ attrs['custom_fields'].select! {|c| editable_custom_field_ids.include?(c['id'].to_s)}
end
# mass-assignment security bypass
@@ -733,7 +744,7 @@ class Issue < ActiveRecord::Base
def assignable_versions
return @assignable_versions if @assignable_versions
- versions = project.shared_versions.open.all
+ versions = project.shared_versions.open.to_a
if fixed_version
if fixed_version_id_changed?
# nothing to do
@@ -879,10 +890,14 @@ class Issue < ActiveRecord::Base
if issues.any?
issue_ids = issues.map(&:id)
# Relations with issue_from in given issues and visible issue_to
- relations_from = IssueRelation.includes(:issue_to => [:status, :project]).where(visible_condition(user)).where(:issue_from_id => issue_ids).all
+ relations_from = IssueRelation.joins(:issue_to => :project).
+ references(:issue_to => :project).
+ where(visible_condition(user)).where(:issue_from_id => issue_ids).to_a
# Relations with issue_to in given issues and visible issue_from
- relations_to = IssueRelation.includes(:issue_from => [:status, :project]).where(visible_condition(user)).where(:issue_to_id => issue_ids).all
-
+ relations_to = IssueRelation.joins(:issue_from => :project).
+ references(:issue_from => :project).
+ where(visible_condition(user)).
+ where(:issue_to_id => issue_ids).to_a
issues.each do |issue|
relations =
relations_from.select {|relation| relation.issue_from_id == issue.id} +
@@ -1121,6 +1136,7 @@ class Issue < ActiveRecord::Base
def parent_issue_id=(arg)
s = arg.to_s.strip.presence
if s && (m = s.match(%r{\A#?(\d+)\z})) && (@parent_issue = Issue.find_by_id(m[1]))
+ @parent_issue.id
@invalid_parent_issue_id = nil
elsif s.blank?
@parent_issue = nil
@@ -1349,7 +1365,7 @@ class Issue < ActiveRecord::Base
self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
cond = ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]
self.class.base_class.select('id').lock(true).where(cond)
- offset = right_most_bound + 1 - lft
+ offset = rdm_right_most_bound + 1 - lft
Issue.where(cond).
update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
end
@@ -1367,6 +1383,14 @@ class Issue < ActiveRecord::Base
recalculate_attributes_for(former_parent_id) if former_parent_id
end
+ def rdm_right_most_bound
+ right_most_node =
+ self.class.base_class.unscoped.
+ order("#{quoted_right_column_full_name} desc").limit(1).lock(true).first
+ right_most_node ? (right_most_node[right_column_name] || 0 ) : 0
+ end
+ private :rdm_right_most_bound
+
def update_parent_attributes
recalculate_attributes_for(parent_id) if parent_id
end
@@ -1395,7 +1419,7 @@ class Issue < ActiveRecord::Base
end
done = p.leaves.joins(:status).
sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " +
- "* (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f
+ "* (CASE WHEN is_closed = #{self.class.connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f
progress = done / (average * leaves_count)
p.done_ratio = progress.round
end
@@ -1415,7 +1439,8 @@ class Issue < ActiveRecord::Base
def self.update_versions(conditions=nil)
# Only need to update issues with a fixed_version from
# a different project and that is not systemwide shared
- Issue.includes(:project, :fixed_version).
+ Issue.joins(:project, :fixed_version).
+ references(:version, :fixed_version).
where("#{Issue.table_name}.fixed_version_id IS NOT NULL" +
" AND #{Issue.table_name}.project_id <> #{Version.table_name}.project_id" +
" AND #{Version.table_name}.sharing <> 'system'").
diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb
index 7bee6f234..e5e508861 100644
--- a/app/models/issue_category.rb
+++ b/app/models/issue_category.rb
@@ -24,6 +24,7 @@ class IssueCategory < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:project_id]
validates_length_of :name, :maximum => 30
+ attr_protected :id
safe_attributes 'name', 'assigned_to_id'
diff --git a/app/models/issue_custom_field.rb b/app/models/issue_custom_field.rb
index a1d16333d..42695e461 100644
--- a/app/models/issue_custom_field.rb
+++ b/app/models/issue_custom_field.rb
@@ -32,7 +32,7 @@ class IssueCustomField < CustomField
sql = super
id_column ||= id
tracker_condition = "#{Issue.table_name}.tracker_id IN (SELECT tracker_id FROM #{table_name_prefix}custom_fields_trackers#{table_name_suffix} WHERE custom_field_id = #{id_column})"
- project_condition = "EXISTS (SELECT 1 FROM #{CustomField.table_name} ifa WHERE ifa.is_for_all = #{connection.quoted_true} AND ifa.id = #{id_column})" +
+ project_condition = "EXISTS (SELECT 1 FROM #{CustomField.table_name} ifa WHERE ifa.is_for_all = #{self.class.connection.quoted_true} AND ifa.id = #{id_column})" +
" OR #{Issue.table_name}.project_id IN (SELECT project_id FROM #{table_name_prefix}custom_fields_projects#{table_name_suffix} WHERE custom_field_id = #{id_column})"
"((#{sql}) AND (#{tracker_condition}) AND (#{project_condition}))"
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb
index c9115100c..9ca0f3077 100644
--- a/app/models/issue_query.rb
+++ b/app/models/issue_query.rb
@@ -45,7 +45,9 @@ class IssueQuery < Query
scope :visible, lambda {|*args|
user = args.shift || User.current
base = Project.allowed_to_condition(user, :view_issues, *args)
- scope = includes(:project).where("#{table_name}.project_id IS NULL OR (#{base})")
+ scope = joins("LEFT OUTER JOIN #{Project.table_name} ON #{table_name}.project_id = #{Project.table_name}.id").
+ references(:project).
+ where("#{table_name}.project_id IS NULL OR (#{base})")
if user.admin?
scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id)
@@ -132,17 +134,17 @@ class IssueQuery < Query
if project
principals += project.principals.sort
unless project.leaf?
- subprojects = project.descendants.visible.all
+ subprojects = project.descendants.visible.to_a
principals += Principal.member_of(subprojects)
end
- versions = project.shared_versions.all
- categories = project.issue_categories.all
+ versions = project.shared_versions.to_a
+ categories = project.issue_categories.to_a
issue_custom_fields = project.all_issue_custom_fields
else
if all_projects.any?
principals += Principal.member_of(all_projects)
end
- versions = Version.visible.where(:sharing => 'system').all
+ versions = Version.visible.where(:sharing => 'system').to_a
issue_custom_fields = IssueCustomField.where(:is_for_all => true)
end
principals.uniq!
@@ -339,7 +341,7 @@ class IssueQuery < Query
scope = scope.preload(:author)
end
- issues = scope.all
+ issues = scope.to_a
if has_column?(:spent_hours)
Issue.load_visible_spent_hours(issues)
@@ -360,12 +362,13 @@ class IssueQuery < Query
joins(:status, :project).
where(statement).
includes(([:status, :project] + (options[:include] || [])).uniq).
+ references(([:status, :project] + (options[:include] || [])).uniq).
where(options[:conditions]).
order(order_option).
joins(joins_for_order_statement(order_option.join(','))).
limit(options[:limit]).
offset(options[:offset]).
- find_ids
+ pluck(:id)
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new(e.message)
end
@@ -380,7 +383,7 @@ class IssueQuery < Query
limit(options[:limit]).
offset(options[:offset]).
preload(:details, :user, {:issue => [:project, :author, :tracker, :status]}).
- all
+ to_a
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new(e.message)
end
@@ -392,7 +395,8 @@ class IssueQuery < Query
where(project_statement).
where(options[:conditions]).
includes(:project).
- all
+ references(:project).
+ to_a
rescue ::ActiveRecord::StatementInvalid => e
raise StatementInvalid.new(e.message)
end
@@ -411,7 +415,7 @@ class IssueQuery < Query
groups = Group.givable
operator = '!' # Override the operator since we want to find by assigned_to
else
- groups = Group.where(:id => value).all
+ groups = Group.where(:id => value).to_a
end
groups ||= []
@@ -431,7 +435,7 @@ class IssueQuery < Query
" WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))"
when "=", "!"
role_cond = value.any? ?
- "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" :
+ "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")" :
"1=0"
sw = operator == "!" ? 'NOT' : ''
@@ -443,7 +447,7 @@ class IssueQuery < Query
def sql_for_is_private_field(field, operator, value)
op = (operator == "=" ? 'IN' : 'NOT IN')
- va = value.map {|v| v == '0' ? connection.quoted_false : connection.quoted_true}.uniq.join(',')
+ va = value.map {|v| v == '0' ? self.class.connection.quoted_false : self.class.connection.quoted_true}.uniq.join(',')
"#{Issue.table_name}.is_private #{op} (#{va})"
end
@@ -462,14 +466,14 @@ class IssueQuery < Query
sql = case operator
when "*", "!*"
op = (operator == "*" ? 'IN' : 'NOT IN')
- "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')"
+ "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}')"
when "=", "!"
op = (operator == "=" ? 'IN' : 'NOT IN')
- "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
+ "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
when "=p", "=!p", "!p"
op = (operator == "!p" ? 'NOT IN' : 'IN')
comp = (operator == "=!p" ? '<>' : '=')
- "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
+ "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
end
if relation_options[:sym] == field && !options[:reverse]
diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb
index d19ff50c5..ba0624a04 100644
--- a/app/models/issue_status.rb
+++ b/app/models/issue_status.rb
@@ -27,6 +27,7 @@ class IssueStatus < ActiveRecord::Base
validates_uniqueness_of :name
validates_length_of :name, :maximum => 30
validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
+ attr_protected :id
scope :sorted, lambda { order("#{table_name}.position ASC") }
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
@@ -79,7 +80,7 @@ class IssueStatus < ActiveRecord::Base
includes(:new_status).
where(["role_id IN (:role_ids) AND tracker_id = :tracker_id AND (#{conditions})",
{:role_ids => roles.collect(&:id), :tracker_id => tracker.id, :true => true, :false => false}
- ]).all.
+ ]).to_a.
map(&:new_status).compact.sort
else
[]
diff --git a/app/models/journal.rb b/app/models/journal.rb
index e3de2b38a..543da42b8 100644
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -24,6 +24,7 @@ class Journal < ActiveRecord::Base
belongs_to :user
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
attr_accessor :indice
+ attr_protected :id
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
:description => :notes,
@@ -34,17 +35,18 @@ class Journal < ActiveRecord::Base
acts_as_activity_provider :type => 'issues',
:author_key => :user_id,
- :find_options => {:include => [{:issue => :project}, :details, :user],
- :conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
- " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
+ :scope => preload({:issue => :project}, :user).
+ joins("LEFT OUTER JOIN #{JournalDetail.table_name} ON #{JournalDetail.table_name}.journal_id = #{Journal.table_name}.id").
+ where("#{Journal.table_name}.journalized_type = 'Issue' AND" +
+ " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')")
before_create :split_private_notes
after_create :send_notification
scope :visible, lambda {|*args|
user = args.shift || User.current
-
- includes(:issue => :project).
+ joins(:issue => :project).
+ references(:project).
where(Issue.visible_condition(user, *args)).
where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
}
diff --git a/app/models/journal_detail.rb b/app/models/journal_detail.rb
index 2557ce87d..e67c19840 100644
--- a/app/models/journal_detail.rb
+++ b/app/models/journal_detail.rb
@@ -18,6 +18,7 @@
class JournalDetail < ActiveRecord::Base
belongs_to :journal
before_save :normalize_values
+ attr_protected :id
def custom_field
if property == 'cf'
diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb
index 4aaa21c98..be737931c 100644
--- a/app/models/mail_handler.rb
+++ b/app/models/mail_handler.rb
@@ -42,7 +42,7 @@ class MailHandler < ActionMailer::Base
@@handler_options[:no_notification] = (@@handler_options[:no_notification].to_s == '1')
@@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1')
- email.force_encoding('ASCII-8BIT') if email.respond_to?(:force_encoding)
+ email.force_encoding('ASCII-8BIT')
super(email)
end
@@ -417,7 +417,7 @@ class MailHandler < ActionMailer::Base
end
parts.reject! do |part|
- part.header[:content_disposition].try(:disposition_type) == 'attachment'
+ part.attachment?
end
@plain_text_body = parts.map do |p|
diff --git a/app/models/member.rb b/app/models/member.rb
index aa1d50cdf..8256d2e68 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -25,6 +25,7 @@ class Member < ActiveRecord::Base
validates_presence_of :principal, :project
validates_uniqueness_of :user_id, :scope => :project_id
validate :validate_role
+ attr_protected :id
before_destroy :set_issue_category_nil
diff --git a/app/models/member_role.rb b/app/models/member_role.rb
index 74d4c631f..038509026 100644
--- a/app/models/member_role.rb
+++ b/app/models/member_role.rb
@@ -26,6 +26,7 @@ class MemberRole < ActiveRecord::Base
validates_presence_of :role
validate :validate_role_member
+ attr_protected :id
def validate_role_member
errors.add :role_id, :invalid if role && !role.member?
diff --git a/app/models/message.rb b/app/models/message.rb
index 576be4763..028a3eb55 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -22,9 +22,10 @@ class Message < ActiveRecord::Base
acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
acts_as_attachable
belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id'
+ attr_protected :id
acts_as_searchable :columns => ['subject', 'content'],
- :include => {:board => :project},
+ :scope => preload(:board => :project),
:project_key => "#{Board.table_name}.project_id",
:date_column => "#{table_name}.created_on"
acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
@@ -34,7 +35,7 @@ class Message < ActiveRecord::Base
:url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
{:id => o.parent_id, :r => o.id, :anchor => "message-#{o.id}"})}
- acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]},
+ acts_as_activity_provider :scope => preload({:board => :project}, :author),
:author_key => :author_id
acts_as_watchable
@@ -48,7 +49,9 @@ class Message < ActiveRecord::Base
after_create :send_notification
scope :visible, lambda {|*args|
- includes(:board => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+ joins(:board => :project).
+ references(:board => :project).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
}
safe_attributes 'subject', 'content'
diff --git a/app/models/news.rb b/app/models/news.rb
index b86e3f63d..baaa92fba 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -19,16 +19,18 @@ class News < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
- has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
+ has_many :comments, lambda {order("created_on")}, :as => :commented, :dependent => :delete_all
validates_presence_of :title, :description
validates_length_of :title, :maximum => 60
validates_length_of :summary, :maximum => 255
+ attr_protected :id
acts_as_attachable :delete_permission => :manage_news
- acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project
+ acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"],
+ :scope => preload(:project)
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
- acts_as_activity_provider :find_options => {:include => [:project, :author]},
+ acts_as_activity_provider :scope => preload(:project, :author),
:author_key => :author_id
acts_as_watchable
@@ -36,7 +38,9 @@ class News < ActiveRecord::Base
after_create :send_notification
scope :visible, lambda {|*args|
- includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args))
+ joins(:project).
+ references([:author, :project]).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args))
}
safe_attributes 'title', 'summary', 'description'
@@ -68,7 +72,7 @@ class News < ActiveRecord::Base
# returns latest news for projects visible by user
def self.latest(user = User.current, count = 5)
- visible(user).includes([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).all
+ visible(user).joins([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).to_a
end
private
diff --git a/app/models/principal.rb b/app/models/principal.rb
index 1bbbbe88e..d10241b3f 100644
--- a/app/models/principal.rb
+++ b/app/models/principal.rb
@@ -25,11 +25,13 @@ class Principal < ActiveRecord::Base
STATUS_LOCKED = 3
has_many :members, :foreign_key => 'user_id', :dependent => :destroy
- has_many :memberships, :class_name => 'Member',
- :foreign_key => 'user_id',
- :include => [:project, :roles],
- :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}",
- :order => "#{Project.table_name}.name"
+ has_many :memberships,
+ lambda {preload(:project, :roles).
+ joins(:project).
+ where("#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}").
+ order("#{Project.table_name}.name")},
+ :class_name => 'Member',
+ :foreign_key => 'user_id'
has_many :projects, :through => :memberships
has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
@@ -56,8 +58,8 @@ class Principal < ActiveRecord::Base
# Principals that are members of a collection of projects
scope :member_of, lambda {|projects|
- projects = [projects] unless projects.is_a?(Array)
- if projects.empty?
+ projects = [projects] if projects.is_a?(Project)
+ if projects.blank?
where("1=0")
else
ids = projects.map(&:id)
diff --git a/app/models/project.rb b/app/models/project.rb
index 6a428b209..c2b8af134 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -28,31 +28,35 @@ class Project < ActiveRecord::Base
# Specific overridden Activities
has_many :time_entry_activities
- has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
+ has_many :members,
+ lambda { joins(:principal, :roles).
+ references(:principal, :roles).
+ where("#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}") }
has_many :memberships, :class_name => 'Member'
- has_many :member_principals, :class_name => 'Member',
- :include => :principal,
- :conditions => "#{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
-
+ has_many :member_principals,
+ lambda { joins(:principal).
+ references(:principal).
+ where("#{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}")},
+ :class_name => 'Member'
has_many :enabled_modules, :dependent => :delete_all
- has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
- has_many :issues, :dependent => :destroy, :include => [:status, :tracker]
+ has_and_belongs_to_many :trackers, lambda {order("#{Tracker.table_name}.position")}
+ has_many :issues, :dependent => :destroy
has_many :issue_changes, :through => :issues, :source => :journals
- has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
+ has_many :versions, lambda {order("#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC")}, :dependent => :destroy
has_many :time_entries, :dependent => :destroy
has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all
has_many :documents, :dependent => :destroy
- has_many :news, :dependent => :destroy, :include => :author
- has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
- has_many :boards, :dependent => :destroy, :order => "position ASC"
- has_one :repository, :conditions => ["is_default = ?", true]
+ has_many :news, lambda {includes(:author)}, :dependent => :destroy
+ has_many :issue_categories, lambda {order("#{IssueCategory.table_name}.name")}, :dependent => :delete_all
+ has_many :boards, lambda {order("position ASC")}, :dependent => :destroy
+ has_one :repository, lambda {where(["is_default = ?", true])}
has_many :repositories, :dependent => :destroy
has_many :changesets, :through => :repository
has_one :wiki, :dependent => :destroy
# Custom field for the project issues
has_and_belongs_to_many :issue_custom_fields,
+ lambda {order("#{CustomField.table_name}.position")},
:class_name => 'IssueCustomField',
- :order => "#{CustomField.table_name}.position",
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
:association_foreign_key => 'custom_field_id'
@@ -126,9 +130,9 @@ class Project < ActiveRecord::Base
if !initialized.key?('trackers') && !initialized.key?('tracker_ids')
default = Setting.default_projects_tracker_ids
if default.is_a?(Array)
- self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all
+ self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.to_a
else
- self.trackers = Tracker.sorted.all
+ self.trackers = Tracker.sorted.to_a
end
end
end
@@ -144,7 +148,7 @@ class Project < ActiveRecord::Base
# returns latest created projects
# non public projects will be returned only if user is a member of those
def self.latest(user=nil, count=5)
- visible(user).limit(count).order("created_on DESC").all
+ visible(user).limit(count).order("created_on DESC").to_a
end
# Returns true if the project is visible to +user+ or to the current user.
@@ -212,9 +216,9 @@ class Project < ActiveRecord::Base
end
def override_roles(role)
- @override_members ||= memberships.where(:user_id => [GroupAnonymous.instance_id, GroupNonMember.instance_id]).all
- member = @override_members.detect {|m| role.anonymous? ^ (m.user_id == GroupNonMember.instance_id)}
- member ? member.roles : [role]
+ group_class = role.anonymous? ? GroupAnonymous : GroupNonMember
+ member = member_principals.where("#{Principal.table_name}.type = ?", group_class.name).first
+ member ? member.roles.to_a : [role]
end
def principals
@@ -364,7 +368,7 @@ class Project < ActiveRecord::Base
# by the current user
def allowed_parents
return @allowed_parents if @allowed_parents
- @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all
+ @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).to_a
@allowed_parents = @allowed_parents - self_and_descendants
if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?)
@allowed_parents << nil
@@ -435,11 +439,12 @@ class Project < ActiveRecord::Base
@rolled_up_trackers ||=
Tracker.
joins(:projects).
+ references(:project).
joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'").
select("DISTINCT #{Tracker.table_name}.*").
where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt).
sorted.
- all
+ to_a
end
# Closes open and locked project versions that are completed
@@ -457,7 +462,8 @@ class Project < ActiveRecord::Base
def rolled_up_versions
@rolled_up_versions ||=
Version.
- includes(:project).
+ joins(:project).
+ references(:project).
where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED)
end
@@ -465,13 +471,17 @@ class Project < ActiveRecord::Base
def shared_versions
if new_record?
Version.
- includes(:project).
+ joins(:project).
+ references(:project).
+ preload(:project).
where("#{Project.table_name}.status <> ? AND #{Version.table_name}.sharing = 'system'", STATUS_ARCHIVED)
else
@shared_versions ||= begin
r = root? ? self : root
Version.
- includes(:project).
+ joins(:project).
+ references(:project).
+ preload(:project).
where("#{Project.table_name}.id = #{id}" +
" OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" +
" #{Version.table_name}.sharing = 'system'" +
@@ -497,7 +507,7 @@ class Project < ActiveRecord::Base
# Deletes all project's members
def delete_all_members
me, mr = Member.table_name, MemberRole.table_name
- connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})")
+ self.class.connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})")
Member.delete_all(['project_id = ?', id])
end
@@ -728,7 +738,7 @@ class Project < ActiveRecord::Base
project = project.is_a?(Project) ? project : Project.find(project)
to_be_copied = %w(wiki versions issue_categories issues members queries boards)
- to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil?
+ to_be_copied = to_be_copied & Array.wrap(options[:only]) unless options[:only].nil?
Project.transaction do
if save
@@ -740,6 +750,7 @@ class Project < ActiveRecord::Base
save
end
end
+ true
end
# Returns a new unsaved Project instance with attributes copied from +project+
@@ -958,11 +969,10 @@ class Project < ActiveRecord::Base
def copy_queries(project)
project.queries.each do |query|
new_query = IssueQuery.new
- new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria", "user_id", "type")
+ new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria")
new_query.sort_criteria = query.sort_criteria if query.sort_criteria
new_query.project = self
new_query.user_id = query.user_id
- new_query.role_ids = query.role_ids if query.visibility == IssueQuery::VISIBILITY_ROLES
self.queries << new_query
end
end
diff --git a/app/models/query.rb b/app/models/query.rb
index 9ef002c6e..a4d34d1e4 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -288,7 +288,7 @@ class Query < ActiveRecord::Base
end
def trackers
- @trackers ||= project.nil? ? Tracker.sorted.all : project.rolled_up_trackers
+ @trackers ||= project.nil? ? Tracker.sorted.to_a : project.rolled_up_trackers
end
# Returns a hash of localized labels for all filter operators
@@ -306,7 +306,7 @@ class Query < ActiveRecord::Base
end
def all_projects
- @all_projects ||= Project.visible.all
+ @all_projects ||= Project.visible.to_a
end
def all_projects_values
@@ -655,7 +655,7 @@ class Query < ActiveRecord::Base
sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}"
end
else
- sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
+ sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")"
end
else
# IN an empty set
@@ -663,7 +663,7 @@ class Query < ActiveRecord::Base
end
when "!"
if value.any?
- sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
+ sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + "))"
else
# NOT IN an empty set
sql = "1=1"
@@ -705,9 +705,9 @@ class Query < ActiveRecord::Base
end
end
when "o"
- sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id"
+ sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_false})" if field == "status_id"
when "c"
- sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id"
+ sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_true})" if field == "status_id"
when "><t-"
# between today - n days and today
sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0)
@@ -769,9 +769,9 @@ class Query < ActiveRecord::Base
date = Date.today
sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year)
when "~"
- sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
+ sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'"
when "!~"
- sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
+ sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{self.class.connection.quote_string(value.first.to_s.downcase)}%'"
else
raise "Unknown query operator #{operator}"
end
@@ -834,7 +834,7 @@ class Query < ActiveRecord::Base
if self.class.default_timezone == :utc
from = from.utc
end
- s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from)])
+ s << ("#{table}.#{field} > '%s'" % [self.class.connection.quoted_date(from)])
end
if to
if to.is_a?(Date)
@@ -843,7 +843,7 @@ class Query < ActiveRecord::Base
if self.class.default_timezone == :utc
to = to.utc
end
- s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to)])
+ s << ("#{table}.#{field} <= '%s'" % [self.class.connection.quoted_date(to)])
end
s.join(' AND ')
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 25b0e1da8..1cab86bd1 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -25,7 +25,7 @@ class Repository < ActiveRecord::Base
IDENTIFIER_MAX_LENGTH = 255
belongs_to :project
- has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
+ has_many :changesets, lambda{order("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC")}
has_many :filechanges, :class_name => 'Change', :through => :changesets
serialize :extra_info
@@ -45,6 +45,7 @@ class Repository < ActiveRecord::Base
validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
# Checks if the SCM is enabled when creating a repository
validate :repo_create_validation, :on => :create
+ attr_protected :id
safe_attributes 'identifier',
'login',
@@ -264,7 +265,7 @@ class Repository < ActiveRecord::Base
reorder("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC").
limit(limit).
preload(:user).
- all
+ to_a
else
filechanges.
where("path = ?", path.with_leading_slash).
@@ -313,7 +314,8 @@ class Repository < ActiveRecord::Base
return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
user = nil
- c = changesets.where(:committer => committer).includes(:user).first
+ c = changesets.where(:committer => committer).
+ includes(:user).references(:user).first
if c && c.user
user = c.user
elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
@@ -484,10 +486,10 @@ class Repository < ActiveRecord::Base
ci = "#{table_name_prefix}changesets_issues#{table_name_suffix}"
cp = "#{table_name_prefix}changeset_parents#{table_name_suffix}"
- connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
- connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
- connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
- connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
+ self.class.connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+ self.class.connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+ self.class.connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+ self.class.connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
clear_extra_info_of_changesets
end
diff --git a/app/models/repository/cvs.rb b/app/models/repository/cvs.rb
index 09d79c4fb..abc408304 100644
--- a/app/models/repository/cvs.rb
+++ b/app/models/repository/cvs.rb
@@ -199,7 +199,7 @@ class Repository::Cvs < Repository
# Need to retrieve existing revision numbers to sort them as integers
sql = "SELECT revision FROM #{Changeset.table_name} "
sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'"
- @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0)
+ @current_revision_number ||= (self.class.connection.select_values(sql).collect(&:to_i).max || 0)
@current_revision_number += 1
end
end
diff --git a/app/models/repository/git.rb b/app/models/repository/git.rb
index c51a7e58a..978944efc 100644
--- a/app/models/repository/git.rb
+++ b/app/models/repository/git.rb
@@ -241,7 +241,7 @@ class Repository::Git < Repository
def latest_changesets(path,rev,limit=10)
revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
return [] if revisions.nil? || revisions.empty?
- changesets.where(:scmid => revisions.map {|c| c.scmid}).all
+ changesets.where(:scmid => revisions.map {|c| c.scmid}).to_a
end
def clear_extra_info_of_changesets
diff --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb
index abe1dfb70..81dd24d00 100644
--- a/app/models/repository/mercurial.rb
+++ b/app/models/repository/mercurial.rb
@@ -20,7 +20,7 @@ require 'redmine/scm/adapters/mercurial_adapter'
class Repository::Mercurial < Repository
# sort changesets by revision number
has_many :changesets,
- :order => "#{Changeset.table_name}.id DESC",
+ lambda {order("#{Changeset.table_name}.id DESC")},
:foreign_key => 'repository_id'
attr_protected :root_url
@@ -117,9 +117,10 @@ class Repository::Mercurial < Repository
changesets.
includes(:user).
where(latest_changesets_cond(path, rev, limit)).
+ references(:user).
limit(limit).
order("#{Changeset.table_name}.id DESC").
- all
+ to_a
end
def is_short_id_in_db?
diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb
index 532c1f3a2..1659b77f8 100644
--- a/app/models/repository/subversion.rb
+++ b/app/models/repository/subversion.rb
@@ -42,7 +42,7 @@ class Repository::Subversion < Repository
revisions = scm.revisions(path, rev, nil, :limit => limit)
if revisions
identifiers = revisions.collect(&:identifier).compact
- changesets.where(:revision => identifiers).reorder("committed_on DESC").includes(:repository, :user).all
+ changesets.where(:revision => identifiers).reorder("committed_on DESC").includes(:repository, :user).to_a
else
[]
end
diff --git a/app/models/role.rb b/app/models/role.rb
index 10977612d..efd9a334d 100644
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -166,7 +166,7 @@ class Role < ActiveRecord::Base
# Find all the roles that can be given to a project member
def self.find_all_givable
- Role.givable.all
+ Role.givable.to_a
end
# Return the builtin 'non member' role. If the role doesn't exist,
diff --git a/app/models/setting.rb b/app/models/setting.rb
index 532e9d44d..3881f90f1 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -86,6 +86,7 @@ class Setting < ActiveRecord::Base
validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting|
(s = @@available_settings[setting.name]) && s['format'] == 'int'
}
+ attr_protected :id
# Hash used to cache setting values
@cached_settings = {}
@@ -142,6 +143,7 @@ END_SRC
def self.set_from_params(name, params)
params = params.dup
params.delete_if {|v| v.blank? } if params.is_a?(Array)
+ params.symbolize_keys! if params.is_a?(Hash)
m = "#{name}_from_params"
if respond_to? m
diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb
index 662070840..8738668cc 100644
--- a/app/models/time_entry.rb
+++ b/app/models/time_entry.rb
@@ -35,7 +35,7 @@ class TimeEntry < ActiveRecord::Base
acts_as_activity_provider :timestamp => "#{table_name}.created_on",
:author_key => :user_id,
- :find_options => {:include => :project}
+ :scope => preload(:project)
validates_presence_of :user_id, :activity_id, :project_id, :hours, :spent_on
validates_numericality_of :hours, :allow_nil => true, :message => :invalid
@@ -45,13 +45,19 @@ class TimeEntry < ActiveRecord::Base
validate :validate_time_entry
scope :visible, lambda {|*args|
- includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args))
+ joins(:project).
+ references(:project).
+ where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args))
}
scope :on_issue, lambda {|issue|
- includes(:issue).where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}")
+ joins(:issue).
+ references(:issue).
+ where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}")
}
scope :on_project, lambda {|project, include_subprojects|
- includes(:project).where(project.project_condition(include_subprojects))
+ joins(:project).
+ references(:project).
+ where(project.project_condition(include_subprojects))
}
scope :spent_between, lambda {|from, to|
if from && to
diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb
index bd2eef398..05c39f55e 100644
--- a/app/models/time_entry_query.rb
+++ b/app/models/time_entry_query.rb
@@ -42,7 +42,7 @@ class TimeEntryQuery < Query
if project
principals += project.principals.sort
unless project.leaf?
- subprojects = project.descendants.visible.all
+ subprojects = project.descendants.visible.to_a
if subprojects.any?
add_available_filter "subproject_id",
:type => :list_subprojects,
@@ -109,7 +109,8 @@ class TimeEntryQuery < Query
where(statement).
order(order_option).
joins(joins_for_order_statement(order_option.join(','))).
- includes(:activity)
+ includes(:activity).
+ references(:activity)
end
def sql_for_activity_id_field(field, operator, value)
diff --git a/app/models/token.rb b/app/models/token.rb
index b1d2d2905..0f3751030 100644
--- a/app/models/token.rb
+++ b/app/models/token.rb
@@ -18,6 +18,7 @@
class Token < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :value
+ attr_protected :id
before_create :delete_previous_tokens, :generate_new_token
diff --git a/app/models/tracker.rb b/app/models/tracker.rb
index 20ba84527..b4f22c811 100644
--- a/app/models/tracker.rb
+++ b/app/models/tracker.rb
@@ -63,7 +63,7 @@ class Tracker < ActiveRecord::Base
connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{WorkflowTransition.table_name} WHERE tracker_id = #{id} AND type = 'WorkflowTransition'").
flatten.
uniq
- @issue_statuses = IssueStatus.where(:id => ids).all.sort
+ @issue_statuses = IssueStatus.where(:id => ids).to_a.sort
end
def disabled_core_fields
@@ -92,7 +92,7 @@ class Tracker < ActiveRecord::Base
# Returns the fields that are disabled for all the given trackers
def self.disabled_core_fields(trackers)
if trackers.present?
- trackers.uniq.map(&:disabled_core_fields).reduce(:&)
+ trackers.map(&:disabled_core_fields).reduce(:&)
else
[]
end
diff --git a/app/models/user.rb b/app/models/user.rb
index d8590f47c..d86627e85 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -79,8 +79,8 @@ class User < Principal
:after_remove => Proc.new {|user, group| group.user_removed(user)}
has_many :changesets, :dependent => :nullify
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
- has_one :rss_token, :class_name => 'Token', :conditions => "action='feeds'"
- has_one :api_token, :class_name => 'Token', :conditions => "action='api'"
+ has_one :rss_token, lambda {where "action='feeds'"}, :class_name => 'Token'
+ has_one :api_token, lambda {where "action='api'"}, :class_name => 'Token'
belongs_to :auth_source
scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") }
@@ -105,9 +105,13 @@ class User < Principal
validates_length_of :firstname, :lastname, :maximum => 30
validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
validates_length_of :mail, :maximum => MAIL_LENGTH_LIMIT, :allow_nil => true
- validates_confirmation_of :password, :allow_nil => true
validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true
validate :validate_password_length
+ validate do
+ if password_confirmation && password != password_confirmation
+ errors.add(:password, :confirmation)
+ end
+ end
before_create :set_mail_notification
before_save :generate_password_if_needed, :update_hashed_password
@@ -151,6 +155,15 @@ class User < Principal
write_attribute(:mail, arg.to_s.strip)
end
+ def self.find_or_initialize_by_identity_url(url)
+ user = where(:identity_url => url).first
+ unless user
+ user = User.new
+ user.identity_url = url
+ end
+ user
+ end
+
def identity_url=(url)
if url.blank?
write_attribute(:identity_url, '')
@@ -496,10 +509,12 @@ class User < Principal
hash = Hash.new([])
- members = Member.joins(:project).
+ group_class = anonymous? ? GroupAnonymous : GroupNonMember
+ members = Member.joins(:project, :principal).
where("#{Project.table_name}.status <> 9").
- where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Member.table_name}.user_id = ?)", self.id, true, Group.builtin_id(self)).
- preload(:project, :roles)
+ where("#{Member.table_name}.user_id = ? OR (#{Project.table_name}.is_public = ? AND #{Principal.table_name}.type = ?)", self.id, true, group_class.name).
+ preload(:project, :roles).
+ to_a
members.reject! {|member| member.user_id != id && project_ids.include?(member.project_id)}
members.each do |member|
@@ -558,6 +573,8 @@ class User < Principal
# Authorize if user is authorized on every element of the array
context.map {|project| allowed_to?(action, project, options, &block)}.reduce(:&)
end
+ elsif context
+ raise ArgumentError.new("#allowed_to? context argument must be a Project, an Array of projects or nil")
elsif options[:global]
# Admin users are always authorized
return true if admin?
@@ -710,17 +727,17 @@ class User < Principal
return if self.id.nil?
substitute = User.anonymous
- Attachment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
+ Attachment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
Comment.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
Issue.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
Issue.where(['assigned_to_id = ?', id]).update_all('assigned_to_id = NULL')
- Journal.where(['user_id = ?', id]).update_all(['user_id = ?', substitute.id])
+ Journal.where(['user_id = ?', id]).update_all(['user_id = ?', substitute.id])
JournalDetail.
where(["property = 'attr' AND prop_key = 'assigned_to_id' AND old_value = ?", id.to_s]).
update_all(['old_value = ?', substitute.id.to_s])
JournalDetail.
where(["property = 'attr' AND prop_key = 'assigned_to_id' AND value = ?", id.to_s]).
- update_all(['value = ?', substitute.id.to_s])
+ update_all(['value = ?', substitute.id.to_s])
Message.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
News.where(['author_id = ?', id]).update_all(['author_id = ?', substitute.id])
# Remove private queries and keep public ones
diff --git a/app/models/version.rb b/app/models/version.rb
index 1d06360ef..45c7c25a6 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -33,11 +33,14 @@ class Version < ActiveRecord::Base
validates :effective_date, :date => true
validates_inclusion_of :status, :in => VERSION_STATUSES
validates_inclusion_of :sharing, :in => VERSION_SHARINGS
+ attr_protected :id
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
scope :open, lambda { where(:status => 'open') }
scope :visible, lambda {|*args|
- includes(:project).where(Project.allowed_to_condition(args.first || User.current, :view_issues))
+ joins(:project).
+ references(:project).
+ where(Project.allowed_to_condition(args.first || User.current, :view_issues))
}
safe_attributes 'name',
@@ -230,11 +233,6 @@ class Version < ActiveRecord::Base
end
end
- # Returns true if the version is shared, otherwise false
- def shared?
- sharing != 'none'
- end
-
private
def load_issue_counts
diff --git a/app/models/watcher.rb b/app/models/watcher.rb
index 1f42de86f..9981bea1c 100644
--- a/app/models/watcher.rb
+++ b/app/models/watcher.rb
@@ -22,6 +22,7 @@ class Watcher < ActiveRecord::Base
validates_presence_of :user
validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id]
validate :validate_user
+ attr_protected :id
# Returns true if at least one object among objects is watched by user
def self.any_watched?(objects, user)
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index 45a22fda1..b1ce29743 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -18,13 +18,14 @@
class Wiki < ActiveRecord::Base
include Redmine::SafeAttributes
belongs_to :project
- has_many :pages, :class_name => 'WikiPage', :dependent => :destroy, :order => 'title'
+ has_many :pages, lambda {order('title')}, :class_name => 'WikiPage', :dependent => :destroy
has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all
acts_as_watchable
validates_presence_of :start_page
validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
+ attr_protected :id
safe_attributes 'start_page'
diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb
index 415ba9aca..3eac92688 100644
--- a/app/models/wiki_content.rb
+++ b/app/models/wiki_content.rb
@@ -23,6 +23,7 @@ class WikiContent < ActiveRecord::Base
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :text
validates_length_of :comments, :maximum => 255, :allow_nil => true
+ attr_protected :id
acts_as_versioned
@@ -68,13 +69,13 @@ class WikiContent < ActiveRecord::Base
:timestamp => "#{WikiContent.versioned_table_name}.updated_on",
:author_key => "#{WikiContent.versioned_table_name}.author_id",
:permission => :view_wiki_edits,
- :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
- "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
- "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
- "#{WikiContent.versioned_table_name}.id",
- :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
- "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
- "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
+ :scope => select("#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
+ "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
+ "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
+ "#{WikiContent.versioned_table_name}.id").
+ joins("LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
+ "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
+ "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id")
after_destroy :page_update_after_destroy
@@ -104,7 +105,7 @@ class WikiContent < ActiveRecord::Base
# uncompressed data
data
end
- str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
+ str.force_encoding("UTF-8")
str
end
end
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index fc56d9d6b..8aed835ad 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -33,7 +33,7 @@ class WikiPage < ActiveRecord::Base
:url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}}
acts_as_searchable :columns => ['title', "#{WikiContent.table_name}.text"],
- :include => [{:wiki => :project}, :content],
+ :scope => preload(:wiki => :project).joins(:content, {:wiki => :project}),
:permission => :view_wiki_pages,
:project_key => "#{Wiki.table_name}.project_id"
@@ -43,6 +43,7 @@ class WikiPage < ActiveRecord::Base
validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/
validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
validates_associated :content
+ attr_protected :id
validate :validate_parent_title
before_destroy :remove_redirects
@@ -180,12 +181,10 @@ class WikiPage < ActiveRecord::Base
def save_with_content(content)
ret = nil
transaction do
- self.content = content
- if new_record?
- # Rails automatically saves associated content
- ret = save
- else
- ret = save && (content.text_changed? ? content.save : true)
+ ret = save
+ if content.text_changed?
+ self.content = content
+ ret = ret && content.changed?
end
raise ActiveRecord::Rollback unless ret
end
diff --git a/app/models/wiki_redirect.rb b/app/models/wiki_redirect.rb
index 403fb5c52..166453138 100644
--- a/app/models/wiki_redirect.rb
+++ b/app/models/wiki_redirect.rb
@@ -20,4 +20,5 @@ class WikiRedirect < ActiveRecord::Base
validates_presence_of :title, :redirects_to
validates_length_of :title, :redirects_to, :maximum => 255
+ attr_protected :id
end
diff --git a/app/models/workflow_rule.rb b/app/models/workflow_rule.rb
index 829b88a32..3d1b75bd0 100644
--- a/app/models/workflow_rule.rb
+++ b/app/models/workflow_rule.rb
@@ -24,6 +24,7 @@ class WorkflowRule < ActiveRecord::Base
belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
validates_presence_of :role, :tracker, :old_status
+ attr_protected :id
# Copies workflows from source to targets
def self.copy(source_tracker, source_role, target_trackers, target_roles)
@@ -34,7 +35,7 @@ class WorkflowRule < ActiveRecord::Base
target_trackers = [target_trackers].flatten.compact
target_roles = [target_roles].flatten.compact
- target_trackers = Tracker.sorted.all if target_trackers.empty?
+ target_trackers = Tracker.sorted.to_a if target_trackers.empty?
target_roles = Role.all if target_roles.empty?
target_trackers.each do |target_tracker|
diff --git a/app/models/workflow_transition.rb b/app/models/workflow_transition.rb
index 6b04d5983..e88769aa7 100644
--- a/app/models/workflow_transition.rb
+++ b/app/models/workflow_transition.rb
@@ -40,7 +40,7 @@ class WorkflowTransition < WorkflowRule
roles = Array.wrap roles
transaction do
- records = WorkflowTransition.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).all
+ records = WorkflowTransition.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).to_a
transitions.each do |old_status_id, transitions_by_new_status|
transitions_by_new_status.each do |new_status_id, transition_by_rule|
diff --git a/app/views/common/_tabs.html.erb b/app/views/common/_tabs.html.erb
index 454b5d772..ffb7f2afa 100644
--- a/app/views/common/_tabs.html.erb
+++ b/app/views/common/_tabs.html.erb
@@ -8,8 +8,8 @@
<% end -%>
</ul>
<div class="tabs-buttons" style="display:none;">
- <button class="tab-left" type="button" onclick="moveTabLeft(this);"></button>
- <button class="tab-right" type="button" onclick="moveTabRight(this);"></button>
+ <button class="tab-left" onclick="moveTabLeft(this); return false;"></button>
+ <button class="tab-right" onclick="moveTabRight(this); return false;"></button>
</div>
</div>
diff --git a/app/views/groups/_memberships.html.erb b/app/views/groups/_memberships.html.erb
index 777a0df7c..ec275c594 100644
--- a/app/views/groups/_memberships.html.erb
+++ b/app/views/groups/_memberships.html.erb
@@ -1,5 +1,5 @@
<% roles = Role.find_all_givable %>
-<% projects = Project.active.all %>
+<% projects = Project.active.to_a %>
<div class="splitcontentleft">
<% if @group.memberships.any? %>
diff --git a/app/views/projects/settings/_members.html.erb b/app/views/projects/settings/_members.html.erb
index ba7bf91f1..392d1d4b5 100644
--- a/app/views/projects/settings/_members.html.erb
+++ b/app/views/projects/settings/_members.html.erb
@@ -1,6 +1,6 @@
<%= error_messages_for 'member' %>
<% roles = Role.find_all_givable
- members = @project.member_principals.includes(:member_roles, :roles, :principal).all.sort %>
+ members = @project.member_principals.includes(:member_roles, :roles, :principal).to_a.sort %>
<div class="splitcontentleft">
<% if members.any? %>
diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb
index b51f98dad..955c2d06b 100644
--- a/app/views/timelog/_form.html.erb
+++ b/app/views/timelog/_form.html.erb
@@ -8,7 +8,7 @@
<% elsif params[:issue_id] %>
<%= hidden_field_tag 'issue_id', params[:issue_id] %>
<% else %>
- <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project, :include_blank => true) %></p>
+ <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).to_a, :selected => @time_entry.project, :include_blank => true) %></p>
<% end %>
<% end %>
<p>
diff --git a/app/views/users/_memberships.html.erb b/app/views/users/_memberships.html.erb
index c0d8051ae..cd4201727 100644
--- a/app/views/users/_memberships.html.erb
+++ b/app/views/users/_memberships.html.erb
@@ -1,5 +1,5 @@
<% roles = Role.find_all_givable %>
-<% projects = Project.active.all %>
+<% projects = Project.active.to_a %>
<div class="splitcontentleft">
<% if @user.memberships.any? %>
diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb
index 3a5a4709f..40e6b792a 100644
--- a/app/views/wiki/edit.html.erb
+++ b/app/views/wiki/edit.html.erb
@@ -23,7 +23,7 @@
<%= fp.select :parent_id,
content_tag('option', '', :value => '') +
wiki_page_options_for_select(
- @wiki.pages.includes(:parent).all -
+ @wiki.pages.includes(:parent).to_a -
@page.self_and_descendants, @page.parent) %>
</p>
<% end %>
diff --git a/app/views/wiki/rename.html.erb b/app/views/wiki/rename.html.erb
index c1a8f33ac..85319520d 100644
--- a/app/views/wiki/rename.html.erb
+++ b/app/views/wiki/rename.html.erb
@@ -13,7 +13,7 @@
<p><%= f.select :parent_id,
content_tag('option', '', :value => '') +
wiki_page_options_for_select(
- @wiki.pages.includes(:parent).all - @page.self_and_descendants,
+ @wiki.pages.includes(:parent).to_a - @page.self_and_descendants,
@page.parent),
:label => :field_parent_title %></p>
</div>