mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-03 22:41:48 +01:00
More code style fixes
This commit is contained in:
parent
465419f46a
commit
d4c9041ccd
61 changed files with 406 additions and 422 deletions
|
|
@ -31,9 +31,7 @@ class Context < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
validates_presence_of :name, :message => "context must have a name"
|
||||
validates_length_of :name, :maximum => 255, :message => "context name must be less than 256 characters"
|
||||
validates_uniqueness_of :name, :message => "already exists", :scope => "user_id", :case_sensitive => false
|
||||
validates :name, presence: { message: "context must have a name" }, length: { maximum: 255, message: "context name must be less than 256 characters" }, uniqueness: { message: "already exists", scope: "user_id", case_sensitive: false }
|
||||
|
||||
def self.null_object
|
||||
NullContext.new
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class MessageGateway < ActionMailer::Base
|
|||
|
||||
def get_receiving_user_from_mail_header(email)
|
||||
user = get_receiving_user_from_sms_email(get_address(email))
|
||||
Rails.logger.info(user.nil? ? "User unknown": "Email belongs to #{user.login}")
|
||||
Rails.logger.info(user.nil? ? "User unknown" : "Email belongs to #{user.login}")
|
||||
return user
|
||||
end
|
||||
|
||||
|
|
@ -98,8 +98,8 @@ class MessageGateway < ActionMailer::Base
|
|||
return true
|
||||
end
|
||||
|
||||
def sender_is_in_mailmap?(user,email)
|
||||
if SITE_CONFIG['mailmap'].is_a? Hash and SITE_CONFIG['email_dispatch'] == 'to'
|
||||
def sender_is_in_mailmap?(user, email)
|
||||
if (SITE_CONFIG['mailmap'].is_a? Hash) && SITE_CONFIG['email_dispatch'] == 'to'
|
||||
# Look for the sender in the map of allowed senders
|
||||
SITE_CONFIG['mailmap'][user.preference.sms_email].include? email.from[0]
|
||||
else
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@ class Project < ApplicationRecord
|
|||
|
||||
before_create :set_last_reviewed_now
|
||||
|
||||
validates_presence_of :name
|
||||
validates_length_of :name, :maximum => 255
|
||||
validates_uniqueness_of :name, :scope => "user_id", :case_sensitive => true
|
||||
validates :name, presence: true, length: { maximum: 255 }, uniqueness: { scope: :user_id }
|
||||
|
||||
acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'', :top_of_list => 0
|
||||
|
||||
|
|
@ -88,21 +86,21 @@ class Project < ApplicationRecord
|
|||
end
|
||||
|
||||
def needs_review?(user)
|
||||
return active? && ( last_reviewed.nil? ||
|
||||
return active? && (last_reviewed.nil? ||
|
||||
(last_reviewed < Time.current - user.prefs.review_period.days))
|
||||
end
|
||||
|
||||
def blocked?
|
||||
## mutually exclusive for stalled and blocked
|
||||
# blocked is uncompleted project with deferred or pending todos, but no next actions
|
||||
return false if self.completed?
|
||||
return !self.todos.deferred_or_blocked.empty? && self.todos.active.empty?
|
||||
return false if completed?
|
||||
return !todos.deferred_or_blocked.empty? && todos.active.empty?
|
||||
end
|
||||
|
||||
def stalled?
|
||||
# Stalled projects are active projects with no active next actions
|
||||
return false if self.completed? || self.hidden?
|
||||
return !self.todos.deferred_or_blocked.exists? && !self.todos.active.exists?
|
||||
return false if completed? || hidden?
|
||||
return !todos.deferred_or_blocked.exists? && !todos.active.exists?
|
||||
end
|
||||
|
||||
def shortened_name(length = 40)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@ class RecurringTodo < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
validates_presence_of :description, :recurring_period, :target, :ends_on, :context
|
||||
|
||||
validates_length_of :description, :maximum => 100
|
||||
validates_length_of :notes, :maximum => 60_000, :allow_nil => true
|
||||
validates :description, presence: true, length: { maximum: 100 }
|
||||
validates :notes, length: { maximum: 60_000, allow_nil: true }
|
||||
validates :recurring_period, presence: true
|
||||
validates :target, presence: true
|
||||
validates :ends_on, presence: true
|
||||
validates :context, presence: true
|
||||
|
||||
validate :period_validation
|
||||
validate :pattern_specific_validations
|
||||
|
|
@ -118,12 +120,12 @@ class RecurringTodo < ApplicationRecord
|
|||
|
||||
def remove_from_project!
|
||||
self.project = nil
|
||||
self.save
|
||||
save
|
||||
end
|
||||
|
||||
def clear_todos_association
|
||||
unless todos.nil?
|
||||
self.todos.each do |t|
|
||||
todos.each do |t|
|
||||
t.recurring_todo = nil
|
||||
t.save
|
||||
end
|
||||
|
|
@ -132,7 +134,7 @@ class RecurringTodo < ApplicationRecord
|
|||
|
||||
def increment_occurrences
|
||||
self.occurrences_count += 1
|
||||
self.save
|
||||
save
|
||||
end
|
||||
|
||||
def continues_recurring?(previous)
|
||||
|
|
|
|||
|
|
@ -158,13 +158,13 @@ module RecurringTodos
|
|||
|
||||
def continues_recurring?(previous)
|
||||
return @recurring_todo.occurrences_count < @recurring_todo.number_of_occurrences unless @recurring_todo.number_of_occurrences.nil?
|
||||
return true if self.end_date.nil? || self.ends_on == 'no_end_date'
|
||||
return true if end_date.nil? || ends_on == 'no_end_date'
|
||||
|
||||
case self.target
|
||||
case target
|
||||
when 'due_date'
|
||||
get_due_date(previous) <= self.end_date
|
||||
get_due_date(previous) <= end_date
|
||||
when 'show_from_date'
|
||||
get_show_from_date(previous) <= self.end_date
|
||||
get_show_from_date(previous) <= end_date
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ module RecurringTodos
|
|||
# offset needs to be 1.day for daily patterns or the start will be the
|
||||
# same day as the previous
|
||||
def determine_start(previous, offset = 0.day)
|
||||
start = self.start_from || NullTime.new
|
||||
start = start_from || NullTime.new
|
||||
if previous
|
||||
# check if the start_from date is later than previous. If so, use
|
||||
# start_from as start to search for next date
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ module RecurringTodos
|
|||
# get pattern independend attributes
|
||||
filtered_attributes = filter_generic_attributes(attributes)
|
||||
# append pattern specific attributes
|
||||
attributes_to_filter.each{ |key| filtered_attributes[key]= attributes[key] if attributes.key?(key) }
|
||||
attributes_to_filter.each { |key| filtered_attributes[key] = attributes[key] if attributes.key?(key) }
|
||||
|
||||
filtered_attributes
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ module RecurringTodos
|
|||
|
||||
if only_work_days?
|
||||
# jump over weekend if necessary
|
||||
return start + 2.day if start.wday() == 6 # saturday
|
||||
return start + 1.day if start.wday() == 0 # sunday
|
||||
return start + 2.day if start.wday == 6 # saturday
|
||||
return start + 1.day if start.wday == 0 # sunday
|
||||
return start
|
||||
else
|
||||
# if there was no previous todo, do not add n: the first todo starts on
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module RecurringTodos
|
|||
def validate
|
||||
super
|
||||
validate_not_blank(every_x_week, "Every other nth week may not be empty for weekly recurrence setting")
|
||||
something_set = %w{ sunday monday tuesday wednesday thursday friday saturday }.inject(false) { |set, day| set || self.send("on_#{day}") }
|
||||
something_set = %w{ sunday monday tuesday wednesday thursday friday saturday }.inject(false) { |set, day| set || send("on_#{day}") }
|
||||
errors[:base] << "You must specify at least one day on which the todo recurs" unless something_set
|
||||
end
|
||||
|
||||
|
|
@ -41,19 +41,19 @@ module RecurringTodos
|
|||
|
||||
# we did not find anything this week, so check the nth next, starting from
|
||||
# sunday
|
||||
start = start + self.every_x_week.week - (start.wday).days
|
||||
start = start + every_x_week.week - (start.wday).days
|
||||
|
||||
start = find_first_day_in_this_week(start)
|
||||
return start unless start == -1
|
||||
|
||||
raise Exception.new, "unable to find next weekly date (#{self.every_day})"
|
||||
raise Exception.new, "unable to find next weekly date (#{every_day})"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def determine_start_date(previous)
|
||||
if previous.nil?
|
||||
return self.start_from || Time.zone.now
|
||||
return start_from || Time.zone.now
|
||||
else
|
||||
start = previous + 1.day
|
||||
if start.wday == 0
|
||||
|
|
@ -61,10 +61,10 @@ module RecurringTodos
|
|||
# that week. Note that we already went into the next week, so -1
|
||||
start += (every_x_week - 1).week
|
||||
end
|
||||
unless self.start_from.nil?
|
||||
unless start_from.nil?
|
||||
# check if the start_from date is later than previous. If so, use
|
||||
# start_from as start to search for next date
|
||||
start = self.start_from if self.start_from > previous
|
||||
start = start_from if start_from > previous
|
||||
end
|
||||
return start
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ module RecurringTodos
|
|||
end
|
||||
|
||||
def recurrence_pattern
|
||||
if self.recurrence_selector == 0
|
||||
if recurrence_selector == 0
|
||||
I18n.t("todos.recurrence.pattern.every_year_on", :date => date_as_month_day)
|
||||
else
|
||||
I18n.t("todos.recurrence.pattern.every_year_on",
|
||||
|
|
@ -94,11 +94,11 @@ module RecurringTodos
|
|||
the_next = start.month > month ? Time.zone.local(start.year + 1, month, 1) : start
|
||||
|
||||
# get the xth day of the month
|
||||
the_next = get_xth_day_of_month(self.every_xth_day, day_of_week, month, the_next.year)
|
||||
the_next = get_xth_day_of_month(every_xth_day, day_of_week, month, the_next.year)
|
||||
|
||||
# if the_next is before previous, we went back into the past, so try next
|
||||
# year
|
||||
the_next = get_xth_day_of_month(self.every_xth_day, day_of_week, month, start.year + 1) if the_next <= start
|
||||
the_next = get_xth_day_of_month(every_xth_day, day_of_week, month, start.year + 1) if the_next <= start
|
||||
|
||||
the_next
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,33 +19,33 @@ module Search
|
|||
end
|
||||
|
||||
def number_of_finds
|
||||
results[:todos].size + results[:projects].size + results[:notes].size + results[:contexts].size + results[:tags].size
|
||||
results[:todos].size + results[:projects].size + results[:notes].size + results[:contexts].size + results[:tags].size
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def incomplete_todos(terms)
|
||||
@user.todos.
|
||||
where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND todos.completed_at IS NULL", terms, terms)
|
||||
@user.todos
|
||||
.where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND todos.completed_at IS NULL", terms, terms)
|
||||
.includes(Todo::DEFAULT_INCLUDES)
|
||||
.reorder(Arel.sql("todos.due IS NULL, todos.due ASC, todos.created_at ASC"))
|
||||
end
|
||||
|
||||
def complete_todos(terms)
|
||||
@user.todos.
|
||||
where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND NOT (todos.completed_at IS NULL)", terms, terms)
|
||||
@user.todos
|
||||
.where("(todos.description " + Common.like_operator + " ? OR todos.notes " + Common.like_operator + " ?) AND NOT (todos.completed_at IS NULL)", terms, terms)
|
||||
.includes(Todo::DEFAULT_INCLUDES)
|
||||
.reorder("todos.completed_at DESC")
|
||||
end
|
||||
|
||||
def todo_tags_by_name(terms)
|
||||
Tagging.find_by_sql([
|
||||
"SELECT DISTINCT tags.name as name " +
|
||||
"FROM tags " +
|
||||
"LEFT JOIN taggings ON tags.id = taggings.tag_id " +
|
||||
"LEFT JOIN todos ON taggings.taggable_id = todos.id " +
|
||||
"WHERE todos.user_id=? " +
|
||||
"AND tags.name " + Common.like_operator + " ? ", @user.id, terms])
|
||||
Tagging.find_by_sql(["
|
||||
SELECT DISTINCT tags.name as name
|
||||
FROM tags
|
||||
LEFT JOIN taggings ON tags.id = taggings.tag_id
|
||||
LEFT JOIN todos ON taggings.taggable_id = todos.id
|
||||
WHERE todos.user_id = ?
|
||||
AND tags.name " + Common.like_operator + " ? ", @user.id, terms])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ module Stats
|
|||
end
|
||||
|
||||
def convert_to_weeks_running_array(records, array_size)
|
||||
return convert_to_array(records, array_size) { |r| [difference_in_weeks(r.completed_at, r.created_at)]}
|
||||
return convert_to_array(records, array_size) { |r| [difference_in_weeks(r.completed_at, r.created_at)] }
|
||||
end
|
||||
|
||||
def convert_to_weeks_running_from_today_array(records, array_size)
|
||||
|
|
@ -391,7 +391,7 @@ module Stats
|
|||
|
||||
def convert_to_cumulative_array(array, max)
|
||||
# calculate fractions
|
||||
a = Array.new(array.size) {|i| array[i] * 100.0 / max}
|
||||
a = Array.new(array.size) { |i| array[i] * 100.0 / max }
|
||||
# make cumulative
|
||||
1.upto(array.size - 1) { |i| a[i] += a[i - 1] }
|
||||
return a
|
||||
|
|
@ -422,7 +422,7 @@ module Stats
|
|||
def compute_running_avg_array(set, upper_bound)
|
||||
result = set_three_month_avg(set, upper_bound)
|
||||
result[upper_bound - 1] = result[upper_bound - 1] * 3 if upper_bound == set.length
|
||||
result[upper_bound - 2] = result[upper_bound - 2] * 3 / 2 if upper_bound > 1 and upper_bound == set.length
|
||||
result[upper_bound - 2] = result[upper_bound - 2] * 3 / 2 if upper_bound > 1 && upper_bound == set.length
|
||||
result[0] = "null"
|
||||
result
|
||||
end # unsolved, not triggered, edge case for set.length == upper_bound + 1
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module Stats
|
|||
|
||||
def find_top10_longest_running_projects
|
||||
projects = user.projects.order('created_at ASC')
|
||||
projects.sort_by{ |p| p.running_time }.reverse.take(10)
|
||||
projects.sort_by { |p| p.running_time }.reverse.take(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ class Tag < ApplicationRecord
|
|||
|
||||
# If database speed becomes an issue, you could remove these validations and
|
||||
# rescue the ActiveRecord database constraint errors instead.
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name, :scope => "user_id", :case_sensitive => false
|
||||
validates :name, presence: true, uniqueness: { :scope => "user_id", :case_sensitive => false }
|
||||
|
||||
before_create :before_create
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ class Tagging < ApplicationRecord
|
|||
private
|
||||
|
||||
def delete_orphaned_tag
|
||||
tag.destroy if tag and tag.taggings.count == 0
|
||||
tag.destroy if tag && tag.taggings.count == 0
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class Todo < ApplicationRecord
|
|||
|
||||
# state machine
|
||||
include AASM
|
||||
aasm_initial_state = Proc.new { (self.show_from && self.user && (self.show_from > self.user.date)) ? :deferred : :active }
|
||||
aasm_initial_state = Proc.new { (show_from && user && (show_from > user.date)) ? :deferred : :active }
|
||||
|
||||
aasm :column => :state do
|
||||
state :active
|
||||
|
|
@ -100,11 +100,11 @@ class Todo < ApplicationRecord
|
|||
|
||||
# Description field can't be empty, and must be < 100 bytes Notes must be <
|
||||
# 60,000 bytes (65,000 actually, but I'm being cautious)
|
||||
validates_presence_of :description
|
||||
validates_length_of :description, :maximum => MAX_DESCRIPTION_LENGTH
|
||||
validates_length_of :notes, :maximum => MAX_NOTES_LENGTH, :allow_nil => true
|
||||
validates_presence_of :show_from, :if => :deferred?
|
||||
validates_presence_of :context
|
||||
validates :description, presence: true, length: { maximum: MAX_DESCRIPTION_LENGTH }
|
||||
validates :notes, length: { maximum: MAX_NOTES_LENGTH, allow_nil: true }
|
||||
validates :show_from, presence: true, if: :deferred?
|
||||
validates :context, presence: true
|
||||
|
||||
validate :check_show_from_in_future
|
||||
|
||||
def check_show_from_in_future
|
||||
|
|
@ -139,18 +139,18 @@ class Todo < ApplicationRecord
|
|||
end
|
||||
|
||||
def not_part_of_hidden_container?
|
||||
!((self.project && self.project.hidden?) || self.context.hidden?)
|
||||
!((project && project.hidden?) || context.hidden?)
|
||||
end
|
||||
|
||||
# Returns a string with description <context, project>
|
||||
def specification
|
||||
project_name = self.project.is_a?(NullProject) ? "(none)" : self.project.name
|
||||
return "\'#{self.description}\' <\'#{self.context.title}\'; \'#{project_name}\'>"
|
||||
project_name = project.is_a?(NullProject) ? "(none)" : project.name
|
||||
return "\'#{description}\' <\'#{context.title}\'; \'#{project_name}\'>"
|
||||
end
|
||||
|
||||
def save_predecessors
|
||||
unless @predecessor_array.nil? # Only save predecessors if they changed
|
||||
current_array = self.predecessors
|
||||
current_array = predecessors
|
||||
remove_array = current_array - @predecessor_array
|
||||
add_array = @predecessor_array - current_array
|
||||
|
||||
|
|
@ -158,13 +158,13 @@ class Todo < ApplicationRecord
|
|||
remove_array.each do |todo|
|
||||
unless todo.nil?
|
||||
@removed_predecessors << todo
|
||||
self.predecessors.delete(todo)
|
||||
predecessors.delete(todo)
|
||||
end
|
||||
end
|
||||
|
||||
add_array.each do |todo|
|
||||
unless todo.nil?
|
||||
self.predecessors << todo unless self.predecessors.include?(todo)
|
||||
predecessors << todo unless predecessors.include?(todo)
|
||||
else
|
||||
logger.error "Could not find #{todo.description}" # Unexpected since validation passed
|
||||
end
|
||||
|
|
@ -173,7 +173,7 @@ class Todo < ApplicationRecord
|
|||
end
|
||||
|
||||
def touch_predecessors
|
||||
self.touch
|
||||
touch
|
||||
predecessors.each(&:touch_predecessors)
|
||||
end
|
||||
|
||||
|
|
@ -183,10 +183,10 @@ class Todo < ApplicationRecord
|
|||
|
||||
# remove predecessor and activate myself if it was the last predecessor
|
||||
def remove_predecessor(predecessor)
|
||||
self.predecessors.delete(predecessor)
|
||||
if self.predecessors.empty?
|
||||
self.reload # reload predecessors
|
||||
self.activate!
|
||||
predecessors.delete(predecessor)
|
||||
if predecessors.empty?
|
||||
reload # reload predecessors
|
||||
activate!
|
||||
else
|
||||
save!
|
||||
end
|
||||
|
|
@ -196,10 +196,10 @@ class Todo < ApplicationRecord
|
|||
def is_successor?(todo)
|
||||
if self == todo
|
||||
return true
|
||||
elsif self.successors.empty?
|
||||
elsif successors.empty?
|
||||
return false
|
||||
else
|
||||
self.successors.each do |item|
|
||||
successors.each do |item|
|
||||
if item.is_successor?(todo)
|
||||
return true
|
||||
end
|
||||
|
|
@ -213,7 +213,7 @@ class Todo < ApplicationRecord
|
|||
end
|
||||
|
||||
def hidden?
|
||||
self.project.hidden? || self.context.hidden?
|
||||
project.hidden? || context.hidden?
|
||||
end
|
||||
|
||||
def toggle_completion!
|
||||
|
|
@ -229,7 +229,7 @@ class Todo < ApplicationRecord
|
|||
activate
|
||||
else
|
||||
# parse Date objects into the proper timezone
|
||||
date = date.in_time_zone.beginning_of_day if (date.is_a? Date)
|
||||
date = date.in_time_zone.beginning_of_day if date.is_a? Date
|
||||
|
||||
# show_from needs to be set before state_change because of "bug" in aasm.
|
||||
# If show_from is not set, the todo will not validate and thus aasm will not save
|
||||
|
|
@ -258,14 +258,14 @@ class Todo < ApplicationRecord
|
|||
end
|
||||
|
||||
def from_recurring_todo?
|
||||
return self.recurring_todo_id != nil
|
||||
return recurring_todo_id != nil
|
||||
end
|
||||
|
||||
def add_predecessor_list(predecessor_list)
|
||||
return unless predecessor_list.kind_of? String
|
||||
return unless predecessor_list.is_a? String
|
||||
|
||||
@predecessor_array = predecessor_list.split(",").inject([]) do |list, todo_id|
|
||||
predecessor = self.user.todos.find(todo_id.to_i) if todo_id.present?
|
||||
predecessor = user.todos.find(todo_id.to_i) if todo_id.present?
|
||||
list << predecessor unless predecessor.nil?
|
||||
list
|
||||
end
|
||||
|
|
@ -307,7 +307,7 @@ class Todo < ApplicationRecord
|
|||
# value will be a string. In that case convert to array
|
||||
deps = [deps] unless deps.class == Array
|
||||
|
||||
deps.each { |dep| self.add_predecessor(self.user.todos.find(dep.to_i)) if dep.present? }
|
||||
deps.each { |dep| add_predecessor(user.todos.find(dep.to_i)) if dep.present? }
|
||||
end
|
||||
|
||||
alias_method :original_context=, :context=
|
||||
|
|
@ -376,7 +376,7 @@ class Todo < ApplicationRecord
|
|||
|
||||
def destroy
|
||||
# activate successors if they only depend on this action
|
||||
self.pending_successors.each do |successor|
|
||||
pending_successors.each do |successor|
|
||||
successor.uncompleted_predecessors.delete(self)
|
||||
if successor.uncompleted_predecessors.empty?
|
||||
successor.activate!
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ class User < ApplicationRecord
|
|||
# Virtual attribute for the unencrypted password
|
||||
attr_accessor :password
|
||||
|
||||
#for will_paginate plugin
|
||||
cattr_accessor :per_page
|
||||
@@per_page = 25
|
||||
|
||||
|
|
@ -15,11 +14,11 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def update_positions(context_ids)
|
||||
context_ids.each_with_index { |id, position|
|
||||
context = self.detect { |c| c.id == id.to_i }
|
||||
context_ids.each_with_index do |id, position|
|
||||
context = detect { |c| c.id == id.to_i }
|
||||
raise I18n.t('models.user.error_context_not_associated', :context => id, :user => @user.id) if context.nil?
|
||||
context.update_attribute(:position, position + 1)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -29,27 +28,27 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def update_positions(project_ids)
|
||||
project_ids.each_with_index { |id, position|
|
||||
project = self.find_by(id: id.to_i)
|
||||
project_ids.each_with_index do |id, position|
|
||||
project = find_by(id: id.to_i)
|
||||
raise I18n.t('models.user.error_project_not_associated', :project => id, :user => @user.id) if project.nil?
|
||||
project.update_attribute(:position, position + 1)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def projects_in_state_by_position(state)
|
||||
self.select { |p| p.state == state }.sort_by { |p| p.position }
|
||||
select { |p| p.state == state }.sort_by { |p| p.position }
|
||||
end
|
||||
|
||||
def next_from(project)
|
||||
self.offset_from(project, 1)
|
||||
offset_from(project, 1)
|
||||
end
|
||||
|
||||
def previous_from(project)
|
||||
self.offset_from(project, -1)
|
||||
offset_from(project, -1)
|
||||
end
|
||||
|
||||
def offset_from(project, offset)
|
||||
projects = self.projects_in_state_by_position(project.state)
|
||||
projects = projects_in_state_by_position(project.state)
|
||||
position = projects.index(project)
|
||||
return nil if position == 0 && offset < 0
|
||||
projects.at(position + offset)
|
||||
|
|
@ -57,7 +56,7 @@ class User < ApplicationRecord
|
|||
|
||||
def cache_note_counts
|
||||
project_note_counts = Note.group(:project_id).count
|
||||
self.each do |project|
|
||||
each do |project|
|
||||
project.cached_note_count = project_note_counts[project.id] || 0
|
||||
end
|
||||
end
|
||||
|
|
@ -65,7 +64,7 @@ class User < ApplicationRecord
|
|||
def alphabetize(scope_conditions = {})
|
||||
projects = where(scope_conditions)
|
||||
projects = projects.sort_by { |project| project.name.downcase }
|
||||
self.update_positions(projects.map(&:id))
|
||||
update_positions(projects.map(&:id))
|
||||
return projects
|
||||
end
|
||||
|
||||
|
|
@ -75,7 +74,7 @@ class User < ApplicationRecord
|
|||
todos_in_project.reject { |p| p.todos.active.count > 0 }
|
||||
sorted_project_ids = todos_in_project.map(&:id)
|
||||
|
||||
all_project_ids = self.map(&:id)
|
||||
all_project_ids = map(&:id)
|
||||
other_project_ids = all_project_ids - sorted_project_ids
|
||||
|
||||
update_positions(sorted_project_ids + other_project_ids)
|
||||
|
|
@ -108,19 +107,19 @@ class User < ApplicationRecord
|
|||
has_one :preference, dependent: :destroy
|
||||
has_many :attachments, through: :todos
|
||||
|
||||
validates_presence_of :login
|
||||
validates_presence_of :password, if: :password_required?
|
||||
validates_length_of :password, within: 5..72, if: :password_required?
|
||||
validates_presence_of :password_confirmation, if: :password_required?
|
||||
validates_confirmation_of :password
|
||||
validates_length_of :login, within: 3..80
|
||||
validates :login, presence: true, length: { within: 3..80 }
|
||||
validates_uniqueness_of :login, on: :create, :case_sensitive => false
|
||||
validates :password, presence: true, length: { within: 5..72 }, if: :password_required?
|
||||
validates :password_confirmation, presence: true, if: :password_required?
|
||||
validates :password, confirmation: true
|
||||
validates :email, allow_blank: true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
||||
|
||||
validate :validate_auth_type
|
||||
validates :email, :allow_blank => true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
||||
|
||||
before_create :crypt_password, :generate_token
|
||||
before_update :crypt_password
|
||||
before_destroy :destroy_dependencies, :delete_taggings, prepend: true # run before deleting todos, projects, contexts, etc.
|
||||
# Run before deleting todos, projects, contexts, etc.
|
||||
before_destroy :destroy_dependencies, :delete_taggings, prepend: true
|
||||
|
||||
def validate_auth_type
|
||||
unless Tracks::Config.auth_schemes.include?(auth_type)
|
||||
|
|
@ -136,8 +135,8 @@ class User < ApplicationRecord
|
|||
return nil if candidate.nil?
|
||||
|
||||
if Tracks::Config.auth_schemes.include?('database')
|
||||
return candidate if candidate.auth_type == 'database' and
|
||||
candidate.password_matches? pass
|
||||
|
||||
return candidate if (candidate.auth_type == 'database' && candidate.password_matches?(pass))
|
||||
end
|
||||
|
||||
return nil
|
||||
|
|
@ -177,11 +176,11 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def generate_token
|
||||
self.token = Digest::SHA1.hexdigest "#{Time.now.to_i}#{rand}"
|
||||
self.token = Digest::SHA1.hexdigest "#{Time.zone.now.to_i}#{rand}"
|
||||
end
|
||||
|
||||
def remember_token?
|
||||
remember_token_expires_at && Time.now.utc < remember_token_expires_at
|
||||
remember_token_expires_at && Time.zone.now.utc < remember_token_expires_at
|
||||
end
|
||||
|
||||
# These create and unset the fields required for remembering users between browser closes
|
||||
|
|
@ -209,7 +208,7 @@ class User < ApplicationRecord
|
|||
|
||||
def crypt_password
|
||||
return if password.blank?
|
||||
write_attribute("crypted_password", self.create_hash(password)) if password == password_confirmation
|
||||
write_attribute("crypted_password", create_hash(password)) if password == password_confirmation
|
||||
end
|
||||
|
||||
def password_required?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue