From 38f60803cd1c2f499d661bf1f46b3b204349cf36 Mon Sep 17 00:00:00 2001 From: Wendy Date: Mon, 5 Jun 2017 18:36:59 -0400 Subject: [PATCH] Ao3 5022 rails 4 dot 1 (#2927) * AO3-5022 Bump Rails to 4.1.16 * AO3-5022 Remove with_scope on Work model * AO3-5022 Bump Authlogic version * AO3-5022 Bump to Authlogic 3.4.6 * AO3-5022 Resolve old association syntax for archive_faq * Fixes triggering of CSRF protection in bookmarks controller spec `get :action, format: :js` triggers CSRF protection in Rails 4.1 Replace with `xhr :get, :action, format: :js` * Re-adds support for Minitest assertions in Cucumber steps * Fixes Authlogic::Session::Activateion::NotActivated error in logout user step * Fixes login step authlogic bugs * Removes 'group_by' virtual attribute if @fandoms is empty in users controller * Updates syntax for getting all Language ordered by short * Fixes admin invitations feature specs The old syntax `find(:all)` or `find(:first)` is incorrect - find now only accepts one argument, which it expects to be the id of the object it's looking for. This should fix the remaining spec failures in admin_invitations.feature * Fixes syntax for scope on user * Adds link_to_function helper This is in place of rewriting the html/javascript everywhere to be unobtrusive: http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive_javascript Which is the recommended approach. * Fixes query syntax in scope in Question model * Fixes MySql2 syntax error by calling 'size' instead of 'count' The bug this is addressing is described here: https://github.com/rails/rails/issues/15138 I chose to use `size` in these cases because the collections are already loading. This by-steps the bug and isn't making another call to the database. * Fixes problem with AR query in SeriesController * Fix AR queries in Pseud model * Fixes the calling of a virtual attribute on an empty array of Fandom objects in the pseuds controller * Fixes AR query syntax errors found in comments_and_kudos/kudos.feature * Refactors helper method to eliminate bug Can't call `size` on a collection that hasn't been loaded, and `count` needs to go because of the known 4.1 but with select and count. * Fixes AR query syntax in pseud model scope * Fixes MySql count with select bug in challenge assignments partial Removes whitespace * Fixes bug where `size` was being called on `nil` * Fixes bug with order of operations one = 'one' && true will make one == true and return true (one = 'one') && true will make one == 'one' and return true * Adds rails_select_on_includes gem This fixes a problem raised in the UsersController (and potentially elsewhere) where Mysql was blowing up because a virtual attribute defined in a select statement wasn't a database column. See the issue this is discussed in: https://github.com/rails/rails/issues/15185 And the Gem: https://github.com/alekseyl/rails_select_on_includes * Commits Gemfile.lock * Fixes `Mysql2::Error: Unknown column 'users.login'` in pseud model Eager loading the user in two queries in the pseud model (the `by_byline` scope and the `parse_byline` method) was causing Mysql to throw an Unknown column error. Using a join instead fixes the problem. * Fixes problem with includes statement The includes statements in question referenced a has_many association that used conditions (approved_conditions) that applied to an association of the association. (`Work.includes(:approved_collections)` where `approved_collections` are conditions that have collections that meet a certain criteria). By moving the scopes that determine whether a collection is approved/rejected/approved by user into the collectible model, the Work model doesn't have to guess what is meant by the reference to the columns `collection_items.attributes`. * Removes rails_select_on_includes It caused all other previously passing tests to start failing and didn't end up actually solving the problem it was supposed to. * Calls load on @fandoms in UsersController to make sure it's loaded before the view calls `.empty?` on it * Fixes `find :all` reference * Fixes outdated `find :all` reference * Fixes 'count' bug * Fixes typo in pseud model scope * Fixes outdated `find :all` syntax in media and tags controllers * Calls `load` on @fandoms variable in pseuds controller to prevent `empty?` from erroring out when it's called on @fandoms in the view * Fixes outed `find(:first...) syntax in app/helpers/tag_helpers * Adds Authlogic fix to tag steps that need it * Fixes variable reference * Fixes Authlogic problem with deleting account step * Fixes feature failures in users caused by outdated `find :all` syntax * Fixes works feature failures by updated outdated `find :all` syntax * Fixes challenge_signups_controller_spec failure * Fixes get requests with js format returning cross origin not allowed error in comments controller spec * Checks that expected params exist before passing them to update_attributes * Fixes get ... format: :js line to not raise cross origin error * Fixes outdated `find(:all)` syntax in tags controller * Try * Assign varible * Try this * And the second case * Corgis are still lovely * Fixes mysql syntax problem with `count` in SpamReport method * Shortens syntax in external authors controller conditional * Adds TODO/note about link_to_function definition * Fixes typo in work model * Removes duplicate line in user step definition * Removes comment for useless gem * Makes stylistic change - `size == 0` is better as `size.zero?` --- Gemfile | 4 +- Gemfile.lock | 108 ++++++++++-------- .../admin/admin_invitations_controller.rb | 4 +- .../admin/admin_users_controller.rb | 1 + .../external_authors_controller.rb | 2 +- app/controllers/media_controller.rb | 2 +- app/controllers/pseuds_controller.rb | 8 +- app/controllers/series_controller.rb | 2 +- app/controllers/tags_controller.rb | 8 +- app/controllers/users_controller.rb | 10 +- app/helpers/application_helper.rb | 13 +++ app/helpers/challenge_helper.rb | 35 ++++-- app/helpers/tags_helper.rb | 2 +- app/models/archive_faq.rb | 5 +- app/models/bookmark.rb | 2 +- app/models/collection.rb | 27 +++++ app/models/invite_request.rb | 6 +- app/models/pseud.rb | 53 ++++----- app/models/question.rb | 2 +- app/models/spam_report.rb | 2 +- app/models/user.rb | 8 +- app/models/work.rb | 4 +- .../confirm_delete_user_creations.html.erb | 10 +- .../_maintainer_index_defaulted.html.erb | 9 +- app/views/layouts/_header.html.erb | 2 +- app/views/users/_contents.html.erb | 4 +- app/views/works/_standard_form.html.erb | 2 +- app/views/works/edit_multiple.html.erb | 2 +- features/step_definitions/tag_steps.rb | 17 ++- features/step_definitions/user_steps.rb | 18 ++- features/support/minitest.rb | 3 + lib/collectible.rb | 9 +- spec/controllers/bookmarks_controller_spec.rb | 4 +- .../challenge_signups_controller_spec.rb | 5 +- spec/controllers/comments_controller_spec.rb | 6 +- spec/controllers/inbox_controller_spec.rb | 2 +- 36 files changed, 249 insertions(+), 152 deletions(-) create mode 100644 features/support/minitest.rb diff --git a/Gemfile b/Gemfile index 47594014e50..a2a2abab286 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem 'test-unit', '~> 3.0' gem 'bundler' -gem 'rails', '4.0.13' +gem 'rails', '4.1.16' gem 'rails-observers' gem 'actionpack-page_caching' @@ -74,7 +74,7 @@ gem 'fastimage' # Gems for authentication gem 'devise' gem 'devise-async' # To mails through queues -gem 'authlogic', '~> 3.3.0' +gem 'authlogic', '~> 3.4.6' gem 'bcrypt' # A highly updated version of the authorization plugin diff --git a/Gemfile.lock b/Gemfile.lock index 7ceae6b3bba..544b02506e6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,57 +2,61 @@ GEM remote: https://rubygems.org/ specs: aaronh-chronic (0.3.9) - actionmailer (4.0.13) - actionpack (= 4.0.13) + actionmailer (4.1.16) + actionpack (= 4.1.16) + actionview (= 4.1.16) mail (~> 2.5, >= 2.5.4) - actionpack (4.0.13) - activesupport (= 4.0.13) - builder (~> 3.1.0) - erubis (~> 2.7.0) + actionpack (4.1.16) + actionview (= 4.1.16) + activesupport (= 4.1.16) rack (~> 1.5.2) rack-test (~> 0.6.2) actionpack-page_caching (1.1.0) actionpack (>= 4.0.0, < 6) - activemodel (4.0.13) - activesupport (= 4.0.13) - builder (~> 3.1.0) - activerecord (4.0.13) - activemodel (= 4.0.13) - activerecord-deprecated_finders (~> 1.0.2) - activesupport (= 4.0.13) - arel (~> 4.0.0) - activerecord-deprecated_finders (1.0.4) + actionview (4.1.16) + activesupport (= 4.1.16) + builder (~> 3.1) + erubis (~> 2.7.0) + activemodel (4.1.16) + activesupport (= 4.1.16) + builder (~> 3.1) + activerecord (4.1.16) + activemodel (= 4.1.16) + activesupport (= 4.1.16) + arel (~> 5.0.0) activerecord-mysql-reconnect (0.4.0) activerecord mysql2 - activesupport (4.0.13) + activesupport (4.1.16) i18n (~> 0.6, >= 0.6.9) - minitest (~> 4.2) - multi_json (~> 1.3) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) thread_safe (~> 0.1) - tzinfo (~> 0.3.37) + tzinfo (~> 1.1) acts_as_list (0.9.5) activerecord (>= 3.0) addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) akismetor (1.0.0) ansi (1.5.0) - arel (4.0.2) + arel (5.0.1.20140414130214) audited (4.4.1) activerecord (>= 4.0, < 5.2) - authlogic (3.3.0) + authlogic (3.4.6) activerecord (>= 3.2) activesupport (>= 3.2) - aws-sdk (2.9.17) - aws-sdk-resources (= 2.9.17) - aws-sdk-core (2.9.17) + request_store (~> 1.0) + scrypt (>= 1.2, < 3.0) + aws-sdk (2.9.18) + aws-sdk-resources (= 2.9.18) + aws-sdk-core (2.9.18) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-resources (2.9.17) - aws-sdk-core (= 2.9.17) + aws-sdk-resources (2.9.18) + aws-sdk-core (= 2.9.18) aws-sigv4 (1.0.0) bcrypt (3.1.11) - builder (3.1.4) + builder (3.2.3) bullet (5.0.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.9.0) @@ -166,6 +170,9 @@ GEM multipart-post (>= 1.2, < 3) fastimage (2.1.0) ffi (1.9.18) + ffi-compiler (1.0.1) + ffi (>= 1.0.0) + rake gherkin (3.2.0) globalize (4.0.3) activemodel (>= 4.0.0, < 5) @@ -177,18 +184,18 @@ GEM htmlentities (4.3.4) http-cookie (1.0.3) domain_name (~> 0.5) - httparty (0.15.2) + httparty (0.15.3) multi_xml (>= 0.5.2) i18n (0.8.1) jmespath (1.3.1) - json (2.1.0) + json (1.8.6) kgio (2.10.0) launchy (2.4.3) addressable (~> 2.3) - lograge (0.5.0) - actionpack (>= 4, <= 5.1.0) - activesupport (>= 4, <= 5.1.0) - railties (>= 4, <= 5.1.0) + lograge (0.5.1) + actionpack (>= 4, < 5.2) + activesupport (>= 4, < 5.2) + railties (>= 4, < 5.2) mail (2.6.5) mime-types (>= 1.16, < 4) mechanize (2.7.5) @@ -204,7 +211,7 @@ GEM mime-types (2.99.3) mimemagic (0.3.0) mini_portile2 (2.1.0) - minitest (4.7.5) + minitest (5.10.2) mono_logger (1.1.0) multi_json (1.12.1) multi_test (0.1.2) @@ -266,19 +273,21 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.0.13) - actionmailer (= 4.0.13) - actionpack (= 4.0.13) - activerecord (= 4.0.13) - activesupport (= 4.0.13) + rails (4.1.16) + actionmailer (= 4.1.16) + actionpack (= 4.1.16) + actionview (= 4.1.16) + activemodel (= 4.1.16) + activerecord (= 4.1.16) + activesupport (= 4.1.16) bundler (>= 1.3.0, < 2.0) - railties (= 4.0.13) + railties (= 4.1.16) sprockets-rails (~> 2.0) rails-observers (0.1.2) activemodel (~> 4.0) - railties (4.0.13) - actionpack (= 4.0.13) - activesupport (= 4.0.13) + railties (4.1.16) + actionpack (= 4.1.16) + activesupport (= 4.1.16) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.18.0) @@ -286,6 +295,7 @@ GEM redis (3.3.3) redis-namespace (1.5.3) redis (~> 3.0, >= 3.0.4) + request_store (1.3.2) responders (1.1.2) railties (>= 3.2, < 4.2) resque (1.27.4) @@ -339,6 +349,9 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.4.4) nokogumbo (~> 1.4.1) + scrypt (2.1.1) + ffi-compiler (>= 0.0.2) + rake selenium-webdriver (3.4.0) childprocess (~> 0.5) rubyzip (~> 1.0) @@ -378,7 +391,7 @@ GEM tilt (2.0.7) timecop (0.8.1) timeliness (0.3.8) - tins (1.13.2) + tins (1.13.3) tire (0.6.2) activemodel (>= 3.0) activesupport @@ -392,7 +405,8 @@ GEM transaction_retry (1.0.2) activerecord (>= 3.0.11) transaction_isolation (>= 1.0.2) - tzinfo (0.3.53) + tzinfo (1.2.3) + thread_safe (~> 0.1) unf (0.1.4) unf_ext unf_ext (0.0.7.4) @@ -436,7 +450,7 @@ DEPENDENCIES addressable akismetor audited (~> 4.4) - authlogic (~> 3.3.0) + authlogic (~> 3.4.6) aws-sdk bcrypt bullet (~> 5.0.0) @@ -486,7 +500,7 @@ DEPENDENCIES poltergeist pry-byebug rack-dev-mark (>= 0.7.5) - rails (= 4.0.13) + rails (= 4.1.16) rails-observers redis (>= 3.0) redis-namespace diff --git a/app/controllers/admin/admin_invitations_controller.rb b/app/controllers/admin/admin_invitations_controller.rb index 8fef825bedb..1f72a9306ed 100644 --- a/app/controllers/admin/admin_invitations_controller.rb +++ b/app/controllers/admin/admin_invitations_controller.rb @@ -19,7 +19,7 @@ def create end def invite_from_queue - InviteRequest.find(:all, order: :position, limit: invitation_params[:invite_from_queue].to_i).each do |request| + InviteRequest.order(:position).limit(invitation_params[:invite_from_queue].to_i).each do |request| request.invite_and_remove(current_admin) end InviteRequest.reset_order @@ -46,7 +46,7 @@ def find if !invitation_params[:token].blank? @invitation = Invitation.find_by(token: invitation_params[:token]) elsif !invitation_params[:invitee_email].blank? - @invitations = Invitation.find(:all, conditions: ['invitee_email LIKE ?', '%' + invitation_params[:invitee_email] + '%']) + @invitations = Invitation.where('invitee_email LIKE ?', "%#{invitation_params[:invitee_email]}%") @invitation = @invitations.first if @invitations.length == 1 end unless @user || @invitation || @invitations diff --git a/app/controllers/admin/admin_users_controller.rb b/app/controllers/admin/admin_users_controller.rb index fa7680ec632..7ce5d66eaa1 100644 --- a/app/controllers/admin/admin_users_controller.rb +++ b/app/controllers/admin/admin_users_controller.rb @@ -211,6 +211,7 @@ def notify else letter = "0" end + @all_users = User.alphabetical.starting_with(letter) @roles = Role.assignable.uniq end diff --git a/app/controllers/external_authors_controller.rb b/app/controllers/external_authors_controller.rb index 37fccf24fc5..eb120409c16 100644 --- a/app/controllers/external_authors_controller.rb +++ b/app/controllers/external_authors_controller.rb @@ -76,7 +76,7 @@ def update end @invitation.mark_as_redeemed if @invitation && !params[:imported_stories].blank? - if @external_author.update_attributes(external_author_params[:external_author]) + if @external_author.update_attributes(external_author_params[:external_author] || {}) flash[:notice] += "Your preferences have been saved." if @user redirect_to user_external_authors_path(@user) diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb index 8e0b5ba03b2..d74c43096be 100644 --- a/app/controllers/media_controller.rb +++ b/app/controllers/media_controller.rb @@ -8,7 +8,7 @@ def index @fandom_listing = {} @media.each do |medium| if medium == uncategorized - @fandom_listing[medium] = medium.children.in_use.by_type('Fandom').find(:all, :order => 'created_at DESC', :limit => 5) + @fandom_listing[medium] = medium.children.in_use.by_type('Fandom').order('created_at DESC').limit(5) else @fandom_listing[medium] = (logged_in? || logged_in_as_admin?) ? # was losing the select trying to do this through the parents association diff --git a/app/controllers/pseuds_controller.rb b/app/controllers/pseuds_controller.rb index 0f58334c755..3fcdf58a068 100644 --- a/app/controllers/pseuds_controller.rb +++ b/app/controllers/pseuds_controller.rb @@ -14,7 +14,7 @@ def load_user # GET /pseuds.xml def index if @user - @pseuds = @user.pseuds.find(:all) + @pseuds = @user.pseuds @rec_counts = Pseud.rec_counts_for_pseuds(@pseuds) @work_counts = Pseud.work_counts_for_pseuds(@pseuds) @page_subtitle = @user.login @@ -40,7 +40,7 @@ def show @fandoms = Fandom.select("tags.*, count(tags.id) as work_count"). joins(:direct_filter_taggings). joins("INNER JOIN works ON filter_taggings.filterable_id = works.id AND filter_taggings.filterable_type = 'Work'"). - group("tags.id").order("work_count DESC"). + group("tags.id"). merge(Work.visible_to_all.revealed.non_anon). merge(Work.joins("INNER JOIN creatorships ON creatorships.creation_id = works.id AND creatorships.creation_type = 'Work' INNER JOIN pseuds ON creatorships.pseud_id = pseuds.id").where("pseuds.id = ?", @pseud.id)) @@ -51,7 +51,7 @@ def show @fandoms = Fandom.select("tags.*, count(tags.id) as work_count"). joins(:direct_filter_taggings). joins("INNER JOIN works ON filter_taggings.filterable_id = works.id AND filter_taggings.filterable_type = 'Work'"). - group("tags.id").order("work_count DESC"). + group("tags.id"). merge(Work.visible_to_registered_user.revealed.non_anon). merge(Work.joins("INNER JOIN creatorships ON creatorships.creation_id = works.id AND creatorships.creation_type = 'Work' INNER JOIN pseuds ON creatorships.pseud_id = pseuds.id").where("pseuds.id = ?", @pseud.id)) @@ -59,7 +59,7 @@ def show visible_series = @pseud.series.visible_to_registered_user visible_bookmarks = @pseud.bookmarks.visible_to_registered_user end - @fandoms = @fandoms.all # force eager loading + @fandoms = @fandoms.order('work_count DESC').load unless @fandoms.empty? @works = visible_works.revealed.non_anon.order("revised_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) @series = visible_series.order("updated_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) @bookmarks = visible_bookmarks.order("updated_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) diff --git a/app/controllers/series_controller.rb b/app/controllers/series_controller.rb index 7122e04a858..74e4f016936 100644 --- a/app/controllers/series_controller.rb +++ b/app/controllers/series_controller.rb @@ -47,7 +47,7 @@ def index # GET /series/1 # GET /series/1.xml def show - @serial_works = @series.serial_works.includes(:work).where('works.posted = ?', true).order(:position).select{ |sw| sw.work.visible(User.current_user) } + @serial_works = @series.serial_works.includes(:work).where('works.posted = ?', true).references(:works).order(:position).select{ |sw| sw.work.visible(User.current_user) } # sets the page title with the data for the series @page_title = @series.unrevealed? ? ts("Mystery Series") : get_page_title(@series.allfandoms.collect(&:name).join(', '), @series.anonymous? ? ts("Anonymous") : @series.allpseuds.collect(&:byline).join(', '), @series.title) if current_user.respond_to?(:subscriptions) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 14a83e654a5..dd474cd8f2a 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -223,9 +223,9 @@ def edit @counts['External Works'] = @tag.visible_external_works_count @counts['Taggings Count'] = @tag.taggings_count - @parents = @tag.parents.find(:all, order: :name).group_by { |tag| tag[:type] } + @parents = @tag.parents.order(:name).group_by { |tag| tag[:type] } @parents['MetaTag'] = @tag.direct_meta_tags.by_name - @children = @tag.children.find(:all, order: :name).group_by { |tag| tag[:type] } + @children = @tag.children.order(:name).group_by { |tag| tag[:type] } @children['SubTag'] = @tag.direct_sub_tags.by_name @children['Merger'] = @tag.mergers.by_name @@ -273,9 +273,9 @@ def update redirect_to url_for(controller: :tags, action: :edit, id: @tag) end else - @parents = @tag.parents.find(:all, order: :name).group_by { |tag| tag[:type] } + @parents = @tag.parents.order(:name).group_by { |tag| tag[:type] } @parents['MetaTag'] = @tag.direct_meta_tags.by_name - @children = @tag.children.find(:all, order: :name).group_by { |tag| tag[:type] } + @children = @tag.children.order(:name).group_by { |tag| tag[:type] } @children['SubTag'] = @tag.direct_sub_tags.by_name @children['Merger'] = @tag.mergers.by_name diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b339ac41320..44b0033c4b8 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -61,7 +61,7 @@ def show visible = visible_items(current_user) - @fandoms = @fandoms.all # force eager loading + @fandoms = @fandoms.order('work_count DESC').load unless @fandoms.empty? @works = visible[:works].revealed.non_anon.order('revised_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) @series = visible[:series].order('updated_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) @bookmarks = visible[:bookmarks].order('updated_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) @@ -254,8 +254,8 @@ def changed_email # DELETE /users/1.xml def destroy @hide_dashboard = true - @works = @user.works.find(:all, conditions: { posted: true }) - @sole_owned_collections = @user.collections.delete_if { |collection| !(collection.all_owners - @user.pseuds).empty? } + @works = @user.works.where(posted: true) + @sole_owned_collections = @user.collections.to_a.delete_if { |collection| !(collection.all_owners - @user.pseuds).empty? } if @works.empty? && @sole_owned_collections.empty? @user.wipeout_unposted_works if @user.unposted_works @@ -369,7 +369,7 @@ def visible_items(current_user) @fandoms = Fandom.select('tags.*, count(tags.id) as work_count') .joins(:direct_filter_taggings) .joins("INNER JOIN works ON filter_taggings.filterable_id = works.id AND filter_taggings.filterable_type = 'Work'") - .group('tags.id').order('work_count DESC') + .group('tags.id') .merge(Work.send(visible_method).revealed.non_anon) .merge(Work.joins("INNER JOIN creatorships ON creatorships.creation_id = works.id AND creatorships.creation_type = 'Work' INNER JOIN pseuds ON creatorships.pseud_id = pseuds.id @@ -444,7 +444,7 @@ def destroy_author @sole_owned_collections.each(&:destroy) end - @works = @user.works.find(:all, conditions: { posted: true }) + @works = @user.works.where(posted: true) if @works.blank? @user.wipeout_unposted_works if @user.unposted_works diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a05a26133e4..3cda0a3a9f5 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -2,6 +2,19 @@ module ApplicationHelper include HtmlCleaner + # TODO: Official recommendation from Rails indicates we should switch to + # unobtrusive JavaScript instead of using anything like `link_to_function` + def link_to_function(name, *args, &block) + html_options = args.extract_options!.symbolize_keys + + function = block_given? ? update_page(&block) : args[0] || '' + + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" + href = html_options[:href] || 'javascript:void(0)' + + content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) + end + # Generates class names for the main div in the application layout def classes_for_main class_names = controller.controller_name + '-' + controller.action_name diff --git a/app/helpers/challenge_helper.rb b/app/helpers/challenge_helper.rb index 7fb46b7e317..e368414a6ab 100644 --- a/app/helpers/challenge_helper.rb +++ b/app/helpers/challenge_helper.rb @@ -16,12 +16,33 @@ def claim_title(claim) # count the number of tag sets used in a challenge def tag_set_count(collection) - if collection && collection.challenge_type.present? - if collection.challenge_type == "GiftExchange" && !collection.challenge.offer_restriction.owned_tag_sets.empty? - collection.challenge.offer_restriction.owned_tag_sets.count - elsif collection.challenge_type == "PromptMeme" && !collection.challenge.request_restriction.owned_tag_sets.empty? - collection.challenge.request_restriction.owned_tag_sets.count - end + if challenge_type_present?(collection) + tag_sets = determine_tag_sets(collection.challenge) + + # use `blank?` instead of `empty?` since there is the possibility that + # `tag_sets` will be nil, and nil does not respond to `blank?` + tag_sets.size unless tag_sets.blank? + end + end + + private + + # Private: Determines whether a collection has a challenge type + # + # Returns a boolean + def challenge_type_present?(collection) + collection && collection.challenge_type.present? + end + + # Private: Determines the collection of owned_tag_sets based on a given + # challenge's class + # + # Returns an ActiveRecord Collection object or nil + def determine_tag_sets(challenge) + if challenge.class.name == 'GiftExchange' + challenge.offer_restriction.owned_tag_sets + elsif challenge.class.name == 'PromptMeme' + challenge.request_restriction.owned_tag_sets end end -end \ No newline at end of file +end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index ec7ee349844..005b62c99ae 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -190,7 +190,7 @@ def tag_comment_link(tag) if count == "0" last_comment = "" else - last_comment = " (last comment: " + tag.total_comments.find(:first, :order => 'created_at DESC').created_at.to_s + ")" + last_comment = " (last comment: " + tag.total_comments.order('created_at DESC').first.created_at.to_s + ")" end link_text = count + " comments" + last_comment link_to link_text, {:controller => :comments, :action => :index, :tag_id => tag} diff --git a/app/models/archive_faq.rb b/app/models/archive_faq.rb index 32c7cc65f00..9ee4b76ff1f 100644 --- a/app/models/archive_faq.rb +++ b/app/models/archive_faq.rb @@ -4,7 +4,7 @@ class ArchiveFaq < ActiveRecord::Base acts_as_list translates :title - has_many :questions, dependent: :destroy, order: :position + has_many :questions, -> { order(:position) }, dependent: :destroy accepts_nested_attributes_for :questions, allow_destroy: true validates :slug, presence: true, uniqueness: true @@ -52,8 +52,7 @@ def email_translations? end def self.reorder(positions) - SortableList.new(self.find(:all, order: 'position ASC')). - reorder_list(positions) + SortableList.new(self.order('position ASC')).reorder_list(positions) end end diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb index 4fa114da19b..0477e7fb767 100644 --- a/app/models/bookmark.rb +++ b/app/models/bookmark.rb @@ -125,7 +125,7 @@ def visible?(current_user=User.current_user) # Returns the number of bookmarks on an item visible to the current user def self.count_visible_bookmarks(bookmarkable, current_user=:false) - bookmarkable.bookmarks.visible.count + bookmarkable.bookmarks.visible.size end # Virtual attribute for external works diff --git a/app/models/collection.rb b/app/models/collection.rb index c033093ae60..6a5f79351c7 100755 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -174,6 +174,33 @@ def title scope :name_only, -> { select("collections.name") } scope :by_title, -> { order(:title) } + scope :approved, -> { + joins(:collection_items) + .where( + collection_items: { + user_approval_status: CollectionItem::APPROVED, + collection_approval_status: CollectionItem::APPROVED + } + ) + } + scope :user_approved, -> { + joins(:collection_items) + .where( + collection_items: { + user_approval_status: CollectionItem::APPROVED + } + ) + } + scope :rejected, -> { + joins(:collection_items) + .where( + collection_items: { + user_approval_status: CollectionItem::REJECTED + } + ) + } + + before_validation :cleanup_url def cleanup_url self.header_image_url = reformat_url(self.header_image_url) if self.header_image_url diff --git a/app/models/invite_request.rb b/app/models/invite_request.rb index 6308a2e1ad2..31aae100ad0 100644 --- a/app/models/invite_request.rb +++ b/app/models/invite_request.rb @@ -7,10 +7,10 @@ class InviteRequest < ActiveRecord::Base # Realign positions if they're incorrect def self.reset_order - first_request = self.find(:first, order: :position) + first_request = order(:position).first unless first_request && first_request.position == 1 - requests = self.find(:all, order: :position) - requests.each_with_index {|request, index| request.update_attribute(:position, index + 1)} + requests = order(:position) + requests.each_with_index {|request, index| request.update_attribute(:position, index + 1)} end end diff --git a/app/models/pseud.rb b/app/models/pseud.rb index 65e6e2c67de..876ace8ac88 100644 --- a/app/models/pseud.rb +++ b/app/models/pseud.rb @@ -159,31 +159,29 @@ def visible_recs_count self.recs.is_public.size end - scope :public_work_count_for, lambda {|pseud_ids| - { - select: "pseuds.id, count(pseuds.id) AS work_count", - joins: :works, - conditions: {works: {posted: true, hidden_by_admin: false, restricted: false}, pseuds: {id: pseud_ids}}, - group: 'pseuds.id' - } + scope :public_work_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS work_count') + .joins(:works) + .where( + pseuds: { id: pseud_ids }, works: { posted: true, hidden_by_admin: false, restricted: false } + ).group('pseuds.id') } - scope :posted_work_count_for, lambda {|pseud_ids| - { - select: "pseuds.id, count(pseuds.id) AS work_count", - joins: :works, - conditions: {works: {posted: true, hidden_by_admin: false}, pseuds: {id: pseud_ids}}, - group: 'pseuds.id' - } + scope :posted_work_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS work_count') + .joins(:works) + .where( + pseuds: { id: pseud_ids }, works: { posted: true, hidden_by_admin: false } + ).group('pseuds.id') } - scope :public_rec_count_for, lambda {|pseud_ids| - { - select: "pseuds.id, count(pseuds.id) AS rec_count", - joins: :bookmarks, - conditions: {bookmarks: {private: false, hidden_by_admin: false, rec: true}, pseuds: {id: pseud_ids}}, - group: 'pseuds.id' - } + scope :public_rec_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS rec_count') + .joins(:bookmarks) + .where( + pseuds: { id: pseud_ids }, bookmarks: { private: false, hidden_by_admin: false, rec: true } + ) + .group('pseuds.id') } def self.rec_counts_for_pseuds(pseuds) @@ -206,6 +204,7 @@ def self.work_counts_for_pseuds(pseuds) else pseuds_with_counts = Pseud.posted_work_count_for(pseuds.collect(&:id)) end + count_hash = {} pseuds_with_counts.each {|p| count_hash[p.id] = p.work_count.to_i} count_hash @@ -218,14 +217,12 @@ def unposted_works # look up by byline - scope :by_byline, lambda {|byline| - { - conditions: ['users.login = ? AND pseuds.name = ?', + scope :by_byline, -> (byline) { + joins(:user) + .where('users.login = ? AND pseuds.name = ?', (byline.include?('(') ? byline.split('(', 2)[1].strip.chop : byline), (byline.include?('(') ? byline.split('(', 2)[0].strip : byline) - ], - include: :user - } + ) } # Produces a byline that indicates the user's name if pseud is not unique @@ -258,7 +255,7 @@ def self.parse_byline(byline, options = {}) conditions = ['pseuds.name = ?', pseud_name] end end - Pseud.includes(:user).where(conditions).references(:user) + Pseud.joins(:user).where(conditions) end # Takes a comma-separated list of bylines diff --git a/app/models/question.rb b/app/models/question.rb index df4e121382c..10f39130865 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -18,7 +18,7 @@ class Question < ActiveRecord::Base long.', max: ArchiveConfig.CONTENT_MAX) - scope :in_order, order: :position + scope :in_order, -> { order(:position) } # Change the positions of the questions in the def self.reorder(positions) diff --git a/app/models/spam_report.rb b/app/models/spam_report.rb index 7f4a17700f5..38781e92781 100644 --- a/app/models/spam_report.rb +++ b/app/models/spam_report.rb @@ -67,7 +67,7 @@ def score_user(user) where("works.created_at > ? AND works.created_at < ?", recent_date, new_date). - posted.not_spam.count + posted.not_spam.size score -= (count * 2) score += ips.uniq.length [new_works, score] diff --git a/app/models/user.rb b/app/models/user.rb index 229bc2a7dae..35e5e0b21ec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -201,7 +201,7 @@ def unread_inbox_comments_count end scope :alphabetical, -> { order(:login) } - scope :starting_with, -> (letter) { { conditions: ["SUBSTR(login,1,1) = ?", letter] } } + scope :starting_with, -> (letter) { where('login like ?', "#{letter}%") } scope :valid, -> { where(banned: false, suspended: false) } scope :out_of_invites, -> { where(out_of_invites: true) } @@ -447,14 +447,14 @@ def create_log_item(options = {}) # Returns true if user is the sole author of a work # Should also be true if the user has used more than one of their pseuds on a work def is_sole_author_of?(item) - other_pseuds = item.pseuds.find(:all) - self.pseuds + other_pseuds = item.pseuds - pseuds self.is_author_of?(item) && other_pseuds.blank? end # Returns array of works where the user is the sole author def sole_authored_works @sole_authored_works = [] - works.find(:all, conditions: "posted = 1").each do |w| + works.where(posted: 1).each do |w| if self.is_sole_author_of?(w) @sole_authored_works << w end @@ -465,7 +465,7 @@ def sole_authored_works # Returns array of the user's co-authored works def coauthored_works @coauthored_works = [] - works.find(:all, conditions: "posted = 1").each do |w| + works.where(posted: 1).each do |w| unless self.is_sole_author_of?(w) @coauthored_works << w end diff --git a/app/models/work.rb b/app/models/work.rb index bfa7669241e..04f6999b3d9 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -1241,9 +1241,7 @@ def self.in_series(series) # find all the works that do not have a tag in the given category (i.e. no fandom, no characters etc.) def self.no_tags(tag_category, options = {}) tags = tag_category.tags - with_scope :find => options do - find(:all).collect {|w| w if (w.tags & tags).empty? }.compact.uniq - end + where(options).collect{|w| w if (w.tags & tags).empty? }.compact.uniq end # Used when admins have disabled filtering diff --git a/app/views/admin/admin_users/confirm_delete_user_creations.html.erb b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb index 76c6c32d8c6..58bd6022cd8 100644 --- a/app/views/admin/admin_users/confirm_delete_user_creations.html.erb +++ b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb @@ -8,20 +8,20 @@

<%= ts("Are you sure you want to delete all the works and comments created by this user, along with their %{bookmarks} bookmarks, %{series} series, and %{collections} collections? This cannot be undone.", - bookmarks: @bookmarks.count, series: @series.count, collections: @collections.count).html_safe %> + bookmarks: @bookmarks.size, series: @series.size, collections: @collections.size).html_safe %>

- <% if @works.count > 0 %> + <% unless @works.size.zero? %>
-

<%= ts("Works")%> (<%= @works.count %>)

+

<%= ts("Works")%> (<%= @works.size %>)

<%= render "works/work_abbreviated_list", works: @works %> <%= will_paginate(@works, param_name: 'works_page') %>
<% end %> - <% if @comments.count > 0 %> + <% unless @comments.size.zero? %>
-

<%= ts("Comments")%> (<%= @comments.count %>)

+

<%= ts("Comments")%> (<%= @comments.size %>)

<%= render "comments/comment_abbreviated_list", comments: @comments %> <%= will_paginate(@comments, :param_name => 'comments_page') %>
diff --git a/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb b/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb index 5e5f014b5c4..8923fcb2d7f 100755 --- a/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb +++ b/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb @@ -6,14 +6,13 @@
<%= link_to assignment.request_byline, collection_signup_path(@collection, assignment.request) %> - <% if - ChallengeAssignment.in_collection(@collection).by_offering_user(assignment.request.pseud.user).defaulted.count == - ChallengeAssignment.in_collection(@collection).by_offering_user(assignment.request.pseud.user).count %> + <% assignments = ChallengeAssignment.in_collection(@collection).by_offering_user(assignment.request.pseud.user) %> + <% if (defaulted = assignments.defaulted) && assignments && defaulted.size == assignments.size %> <%= ts("(Also defaulted)") %> <% end %> -
+
- <%= label_tag "undefault_#{assignment.id}", :class => 'action' do %> + <%= label_tag "undefault_#{assignment.id}", :class => 'action' do %> <%= ts("Undefault") %> <%= assignment.offer_byline %> <%= check_box_tag "undefault_#{assignment.id}" %> <% end %> diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 8e3c0a147eb..e1b1f4384f8 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -31,7 +31,7 @@ <% else %> diff --git a/app/views/users/_contents.html.erb b/app/views/users/_contents.html.erb index ca7d2aa170d..a803f035b67 100755 --- a/app/views/users/_contents.html.erb +++ b/app/views/users/_contents.html.erb @@ -47,7 +47,7 @@