Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #259 - Implements is_first_version and is_last_version attributes #287

Merged
merged 6 commits into from
Apr 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ The tests are run using Guard, either:

or in case the listening does not work, force the use of file polling:

$ guard --force-polling
$ bin/guard guard --force-polling

Press enter to execute all tests. Guard will monitor for changes and the relevant tests will be run as files are modified.

Expand Down
4 changes: 2 additions & 2 deletions app/controllers/admin/scripts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def new
def edit
@script = Script.find(params[:id])

unless @script.is_latest_version?
unless @script.is_last_version?
redirect_to edit_admin_script_path(@script.latest_version), notice: 'You have been redirected to update the latest version of this Script.'
end
end
Expand All @@ -51,7 +51,7 @@ def create
def update
@script = Script.find(params[:id])

unless @script.is_latest_version?
unless @script.is_last_version?
respond_to do |format|
format.html { redirect_to edit_admin_script_path(@script.latest_version), notice: 'You have been redirected to update the latest version of this Script.' }
format.json { respond_change_fail }
Expand Down
27 changes: 10 additions & 17 deletions app/controllers/scripts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@ class ScriptsController < ApplicationController
def index
do_authorize_class

respond_to do |format|
format.json {
@scripts, opts = Settings.api_response.response_advanced(
api_filter_params,
get_recent_scripts,
Script,
Script.filter_settings
)
respond_index(opts)
}
end
@scripts, opts = Settings.api_response.response_advanced(
api_filter_params,
get_scripts,
Script,
Script.filter_settings
)
respond_index(opts)

end

# GET /admin/scripts/:id
# GET /scripts/:id
def show
do_load_resource
do_authorize_instance
Expand All @@ -39,15 +36,11 @@ def filter
respond_filter(filter_response, opts)
end


private


def get_scripts
Script.order(name: :asc).order(created_at: :desc)
end

def get_recent_scripts
Script.all_most_recent_version
end

end
117 changes: 83 additions & 34 deletions app/models/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,64 +14,112 @@ class Script < ActiveRecord::Base
validate :check_version_increase, on: :create

# for the first script in a group, make sure group_id is set to the script's id
after_create :ensure_updated_by_set
after_create :set_group_id

def display_name
"#{self.name} - v. #{self.version}"
end

def latest_version
Script
.where(group_id: self.group_id)
.where(group_id: group_id)
.order(version: :desc)
.first
end

def is_latest_version?
self.id == latest_version.id
end

def most_recent_in_group
def earliest_version
Script
.where(group_id: self.group_id)
.order(created_at: :desc)
.where(group_id: group_id)
.order(version: :asc)
.first
end

def is_most_recent_in_group?
self.id == most_recent_in_group.id
def last_version
if !@last_version && !has_attribute?(:last_version)
@last_version = Script
.where(group_id: group_id)
.maximum(:version)
end

# prioritise value from db query
read_attribute(:last_version) || @last_version
end

def master_script
Script
.where(group_id: self.group_id)
.where(id: self.group_id)
.first
def is_last_version?
self.version == self.last_version
end

def all_versions
Script.where(group_id: self.group_id).order(created_at: :desc)
def first_version
if !@first_version && !has_attribute?(:first_version)
@first_version = Script
.where(group_id: group_id)
.minimum(:version)
end

# prioritise value from db query
read_attribute(:first_version) || @first_version
end

def is_first_version?
self.version == self.first_version
end

# override the default query for the model
def self.default_scope
query = <<-SQL
INNER JOIN (
SELECT "group_id", max("version") AS "last_version", min("version") AS "first_version"
FROM "scripts"
GROUP BY "group_id"
) s2 on ("scripts"."group_id" = "s2"."group_id")
SQL

joins(query).select('"scripts".*, "s2"."last_version", "s2"."first_version"')
end

def self.all_most_recent_version
Script.find_by_sql(
'SELECT s1.*
FROM scripts s1
WHERE s1.version = (
SELECT max(s2.version)
FROM scripts s2
WHERE s1.group_id = s2.group_id
GROUP BY s2.group_id
)
ORDER BY s1.group_id, s1.version;'
)
# a fake reference to the aliased table defined in the default scope
@script_group = Arel::Table.new('s2', @arel_engine)

def all_versions
Script.where(group_id: self.group_id).order(created_at: :desc)
end

def self.filter_settings
{
valid_fields: [:id, :name, :description, :analysis_identifier, :executable_settings_media_type, :version, :created_at, :creator_id],
render_fields: [:id, :name, :description, :analysis_identifier, :executable_settings, :executable_settings_media_type, :version, :created_at, :creator_id],
valid_fields: [:id, :group_id, :name, :description, :analysis_identifier, :executable_settings_media_type,
:version, :created_at, :creator_id, :is_last_version, :is_first_version],
render_fields: [:id, :group_id, :name, :description, :analysis_identifier, :executable_settings,
:executable_settings_media_type, :version, :created_at, :creator_id],
text_fields: [:name, :description, :analysis_identifier, :executable_settings_media_type],
custom_fields: lambda { |item, user|
virtual_fields = {
is_last_version: item.is_last_version?,
is_first_version: item.is_first_version?
}
[item, virtual_fields]
},
field_mappings: [
{
name: :is_last_version,
value: Arel::Nodes::Grouping.new(
Arel::Nodes::InfixOperation.new(
'='.to_sym,
@script_group[:last_version],
Script.arel_table[:version]
)
)
},
{
name: :is_first_version,
value: Arel::Nodes::Grouping.new(
Arel::Nodes::InfixOperation.new(
'='.to_sym,
@script_group[:first_version],
Script.arel_table[:version]
)
)
}
],
controller: :scripts,
action: :filter,
defaults: {
Expand All @@ -86,17 +134,18 @@ def self.filter_settings
def check_version_increase
matching_or_higher_versions =
Script
.unscoped
.where(group_id: self.group_id)
.where('version >= ?', self.version)
if matching_or_higher_versions.count > 0
errors.add(:version, "must be higher than previous versions (#{matching_or_higher_versions.pluck(:version).flatten.join(', ')})")
end
end

def ensure_updated_by_set
def set_group_id
if self.group_id.blank?
self.group_id = self.id
self.save
self.save!
end
end

Expand Down
Loading