#StackBounty: #ruby-on-rails #postgresql #activerecord #ruby-on-rails-5 Query in ActiveRecord for objects that contain one or more ids …

Bounty: 100

I have Rails 5.2 project with three models:

class Post
  has_many :post_tags
  has_many :tags, through: :post_tags
end

class PostTags
  belongs_to :post
  belongs_to :tag
end

class Tags
  has_many :post_tags
  has_many :posts, through: :post_tags
end

I have the a number of arrays of tag ids, e.g:

array_1 = [3, 4, 5]
array_2 = [5, 6, 8]
array_3 = [9, 11, 13]

I want a query that will return posts that are tagged with at least one tag with an id from each of the arrays.

For instance, imagine I have a post with the following tag ids:

> post = Post.find(1)
> post.tag_ids
> [4, 8]

If I ran the query with array_1 and array_2 it would return this post. However if I ran it with array_1, array_2 and array_3 it would not return this post.

I attempted this with the following query:

Post.joins(:tags).where('tags.id IN (?) AND tags.id IN (?)', array_1, array_2)

But this does not return the post.

What should the query be to return the post?

Any help would be greatly appreciated!


Get this bounty!!!

#StackBounty: #ruby-on-rails #http-headers #ruby-on-rails-6 #rack How can I prefix cookies with __Host or __Secure?

Bounty: 50

I am trying to add prefix to session cookies in rails 6.0.3 app but couldn’t find a way to get it done. I have tried adding key to options hash in session store but it didn’t help and breaks my application. I am using auth-logic gem for authentication, I find no way to get it done gracefully but hopping on that there is some way.

conf/initalizers/session_store.rb

opts = {}
if Rails.configuration.host == "myapplication.com"
  opts =  {expire_after: 2.months, domain: :all}
end

unless Rails.env.test?
  opts[:secure] = true
  opts[:same_site] = :none
end
opts[:key] = '__Host-'

Rails.application.config.session_store :active_record_store, **opts

Attached is the screenshot of github cookies. I want my session headers as like in the image (prefixed with __Host-).

enter image description here


Get this bounty!!!

#StackBounty: #ruby-on-rails #ruby Is it possible to call model method in where clause?

Bounty: 100

I have two models

class Project
   has_one: user
end

class User
   # Attributes
   # active: Boolean
   # under_18: Boolean

   def can_work?
     active? && under_18 == false
   end
end

The logic for can_work?

if active is true and under_18 is false then they can work

I want to do something like this but it’s not possible

Project.all.joins(:user).where('users.can_work? = ?', false)

Essentially what I’m looking for is to find all users who can't work

I know I can use Scope, but copying the logic that I specified above in scope is confusing.

Here’s the scenario that I’m looking for

active |  under_18
------------------
   T        T        = F
   T        F        = T
   F        T        = F
   F        F        = F

Thanks


Get this bounty!!!

#StackBounty: #ruby-on-rails #ruby #testing #segmentation-fault #apple-m1 Segmentation fault on M1 running a Rails System Test

Bounty: 50

I’m running a system test in a Rails app on a MacBook M1 Big Sur OS and it’s giving me a segmentation fault error.

I’m using Ruby 2.7.1 installed via rbenv

➜ which ruby
/Users/sc/.rbenv/shims/ruby
➜ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [-darwin20]

Now, the issue comes whenever I run a rails system test.
Our system tests are congigured with the headless_chrome Capybara driver, which has probably (not sure about this) something to do with the segmentation fault error.

This is what I get when I run the test:

    [BUG] Segmentation fault at 0x000000001b543e20
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [-darwin20]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:                    
     * ~/Library/Logs/DiagnosticReports                                     
     * /Library/Logs/DiagnosticReports                                      
   for more details.                                                        
Don't forget to include the above Crash Report log file in bug reports.     

-- Control frame information -----------------------------------------------
c:0001 p:---- s:0003 e:000002 (none) [FINISH]


-- Other runtime information -----------------------------------------------

* Loaded script: rails_test

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 ruby2_keywords.rb
    5 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/-darwin20/enc/encdb.bundle
    6 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/-darwin20/enc/trans/transdb.bundle
    7 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/-darwin20/rbconfig.rb
    8 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/compatibility.rb
    9 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/defaults.rb
   10 /Users/sc/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/deprecate.rb
   And many more lines...

Any ideas on what’s causing this error?


Get this bounty!!!

#StackBounty: #ruby-on-rails #postgresql #activerecord #ruby-on-rails-6 ActiveRecord OR operator slows down query by factor of 10. Why?

Bounty: 500

I have an ActiveRecord query that uses the OR operator to chain together 2 queries. The results come back fine, but the speed of executing the combined query is ~10 times as slow as executing either of the 2 queries in on their own.

We have an Event model and an Invitation model. A User can be invited to an Event by being targeted through an invitation filter, or by being individually invited by having an Invitation record.

So when determining how many users are invited to a particular event, we have to look at all those with Invitations and all those matching the filter. We do that here:

@invited_count = @invited_by_individual.or(@invited_by_filter).distinct.count(:id)

Now, the problem is that when we execute that query, it takes about 1200ms. If we were to do the queries individually, each of them only take about 80ms. So @invited_by_filter.distinct.count and @invited_by_individual.distinct.count both return results in about 80ms, but neither of these is complete on its own.

Is there any way to speed up the query with the OR operator? Why is this happening in the first place?

Here is the SQL generated by the ActiveRecord queries:

Fast, single query:

(79.7ms)  SELECT COUNT(DISTINCT "users"."id") FROM "users" LEFT OUTER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE "invitations"."event_id" = $1  [["event_id", 732]]

Slow, with combined query:

(1220.7ms)  SELECT COUNT(DISTINCT "users"."id") FROM "users" LEFT OUTER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE ("invitations"."event_id" = $1 OR "users"."organization_id" = $2)  [["event_id", 732], ["organization_id", 13]]

Update, here’s the EXPLAIN:

(1418.2ms)  SELECT COUNT(DISTINCT "users"."id") FROM "users" LEFT OUTER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE ("users"."root_organization_id" = $1 OR "invitations"."event_id" = $2)  [["root_organization_id", -1], ["event_id", 749]]
 => 
EXPLAIN for: SELECT COUNT(DISTINCT "users"."id") FROM "users" LEFT OUTER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE ("users"."root_organization_id" = $1 OR "invitations"."event_id" = $2) [["root_organization_id", -1], ["event_id", 749]]
                                                     QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=121781.56..121781.57 rows=1 width=8)
   ->  Hash Right Join  (cost=113248.88..121778.64 rows=1165 width=8)
         Hash Cond: (invitations.user_id = users.id)
         Filter: ((users.root_organization_id = '-1'::integer) OR (invitations.event_id = 749))
         ->  Seq Scan on invitations  (cost=0.00..1299.70 rows=63470 width=8)
         ->  Hash  (cost=93513.28..93513.28 rows=1135328 width=12)
               ->  Seq Scan on users  (cost=0.00..93513.28 rows=1135328 width=12)
(7 rows)

Update 2, EXPLAIN for queries ran individually, does use the indices:

 => 
EXPLAIN for: SELECT COUNT(*) FROM "users" INNER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE "users"."root_organization_id" = $1 [["root_organization_id", -1]]
                                                               QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=19.05..19.06 rows=1 width=8)
   ->  Nested Loop  (cost=0.72..19.05 rows=1 width=0)
         ->  Index Scan using index_users_on_root_organization_id on users  (cost=0.43..4.45 rows=1 width=8)
               Index Cond: (root_organization_id = '-1'::integer)
         ->  Index Only Scan using index_invitations_on_user_id on invitations  (cost=0.29..14.57 rows=3 width=4)
               Index Cond: (user_id = users.id)
(6 rows)```

and

```EXPLAIN for: SELECT COUNT(DISTINCT "users"."id") FROM "users" LEFT OUTER JOIN "invitations" ON "invitations"."user_id" = "users"."id" WHERE "invitations"."event_id" = $1 [["event_id", 749]]
                                                                  QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=536.34..536.35 rows=1 width=8)
   ->  Nested Loop  (cost=0.72..536.19 rows=62 width=8)
         ->  Index Scan using index_invitations_on_event_id on invitations  (cost=0.29..11.98 rows=62 width=4)
               Index Cond: (event_id = 749)
         ->  Index Only Scan using users_pkey on users  (cost=0.43..8.45 rows=1 width=8)
               Index Cond: (id = invitations.user_id)
(6 rows)```


Get this bounty!!!

#StackBounty: #ruby-on-rails #amazon-web-services #amazon-s3 #amazon-cloudfront Rails 6 – Cost risks involved while making a large vide…

Bounty: 200

I have already asked this question on AWS Developer Forum but dont have any answer, hence posting the same question here to get some help.

I have a quite well organized and fast Rails 6 app where users can upload large videos(4gb)/images and also make them public to others. Its using AWS SDK for S3 upload and CloudFront to distribute and make the content available globally.All uploaded videos are transcoded into mp4,HD.Full HD videos using Input S3 bucket - MediaConvert - Lambda - Ootput S3 bucket - Cloudfront workflow.

Now my query is –

  1. As users are allowed to upload upto 4GB of videos and also can make them public, so does this feature of making large videos public will also increase the cost/billing, as the video is public and more and more people will watch it, raising concerns to more incoming request for CloudFront…Can someone correct me here?
  2. If the above point is correct and will happen, what are the ways I can make videos public without effecting the billing/cost, for example using Cache(cloudfront cache) or any other way to minimize the increasing cost.
  3. What are the ways I can allow users to share uploaded videos to share with others, without increasing the AWS billing?


Get this bounty!!!

#StackBounty: #javascript #ruby-on-rails #ruby Rails 6.1.3 link_to route is not working with no error code, simply ignoring it

Bounty: 50

I am using Rails 6.1.3 with Ruby 2.7.2 for a mostly static pages app. The app has a registration form that a student must complete and download as a PDF file to print, persistence is not required at this point. It was working fine with Dhalang (Google’s puppeteer wrap) gem, then I did a Javascript routine for a different part of the app and it stopped to work.
The process should be: A view has a button link_to the route "new_student_url" set up to the "students_controller#new" action which should get the views/students/new to render the _form, At this point I have the button pointing and recognizing the route but when I click on it it just ignores the event; Oddly enough, if I right click the button to ‘open link in a new tab’, it works… =/
I have read several other cases and found that most of them are caused by a Turbolinks issue, so I did review my Turbolinks setup with Webpack and the app/javascript/packs/application.js seems to be ok, please help.

This is the link button:

<%= link_to "Cédula de Registro", new_student_url, class: "btn btn-success btn-lg", style: "color:#fff;", :data => { :turbolink => 'false' } %>

The data: Turbolinks set to false is an attempt to solve the issue found in another post. If I hover the pointer over the button I can see the route is well pointed to

These are my related routes:

  get 'students/nuevo_ingreso', to: 'students#nuevo_ingreso', as: 'nuevo_ingreso'
  resources :students
  controller :students do
    get '/convert/:id', to: 'students#convert', as: 'convert'
    get '/pdf/:id', to: 'students#pdf', as: 'pdf'
  end

I can see the "$rails routes" are well defined and the link point to the right route
This is the students_controller.rb section

class StudentsController < ApplicationController
  before_action :set_student, only: %i[ show edit update destroy pdf ]

  # GET /students or /students.json
  def index
    @students = Student.all
  end

  # GET /pdf
  def pdf
    # this method will be called by Dhalang
  end

  # GET /convert
  def convert
    _url = request.base_url + pdf_path
    _pdf = Dhalang::PDF.get_from_url(_url)
    _file_name = "CEBcedulaInscripcion"
    File.open("#{Rails.root}/public/#{_file_name}.pdf", "w+b") << _pdf
      redirect_to "/#{_file_name}.pdf"
  end

  # GET /students/1 or /students/1.json
  def show
  end

  def nuevo_ingreso
    
  end
  
  # GET /students/new
  def new
    @student = Student.new
  end

  # GET /students/1/edit
  def edit
  end

  # POST /students or /students.json
  def create
    @student = Student.new(student_params)
    
    respond_to do |format|
      if @student.save
        format.html { redirect_to convert_path(@student) }
        format.json { render :show, status: :created, location: @student }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @student.errors, status: :unprocessable_entity }
      end
    end
  end

I am including the view parts just for completeness
This is the students/new.html.erb

<div class="container col-md-6">
  <h1>CÉDULA DE INSCRIPCIÓN</h1>
  <%= render 'form', student: @student %>
</div>
<%= link_to 'Back', students_path %>

And this is the students/_form.html.erb

<%= bootstrap_form_for(@student) do |f| %>

<div class="control-box">
  <h4>Datos Personales</h4>
  <div class="field">
    <%= f.text_field :name, label: "Nombre", class: "form-control-sm" %>
  </div>
  <div class="form-row">
    <div class="col-md-4">
      <div class="field">
        <%= f.text_field :email, label: "Email", class: "form-control-sm" %>
      </div>
    </div>
...
<div class="control-box">
  <h4>Seguridad Social</h4>
  <div class="row">
    <div class="col-md-4">
      <div class="field">
        <%= f.select :security_institution, [["ISSSTE", "ISSSTE"], ["IMSS", "IMSS"], ["SSA", "SSA"], ["Otro", "Otro"]], { label: "¿Cuenta con algún servicio Medico?", wrapper: { class: 'form-control-sm', data: { foo: 'bar' } } }, { class: "selectpicker" } %>
      </div>
    </div>
    <div class="col-md-8">
      <div class="field">
        <%= f.text_area :medical_condition, label: "¿Recibe actualmente algún tratamiento Médico?", class: "form-control-sm" %>
      </div>
    </div>
  </div>
</div>



<div class="container center">
  <div class="row">
    <div class="actions">
      <%= f.submit "Generar PDF", target: "_blank" %>
    </div>
  </div>
</div> 

<% end %>

And lastly, the Gemfile:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.2'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.3'
gem 'pg', '~> 1.1'
gem 'font-awesome-rails'
gem 'mini_racer'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
# Use bootstrap forms
gem 'bootstrap_form', '~> 4.0'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'

gem 'Dhalang'

gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-rails'
end

group :development do
  gem 'web-console', '>= 4.1.0'
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

group :test do
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  gem 'webdrivers'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

This is the javaScript code which is imported ( import "packs/static_pages" ) in the app/javascript/packs/application.js

$(function () {
  $('.menu li:has(ul)').on("click", function(e) {
    e.preventDefault();
    if ($(this).hasClass('activado')) {
      $(this).removeClass('activado');
      $(this).children('ul').slideUp();
    } else {
      $('.menu li ul').slideUp();
      $('.menu li').removeClass('activado');
      $(this).addClass('activado');
      $(this).children('ul').slideDown();
    }
  });
});


Get this bounty!!!

#StackBounty: #ruby-on-rails #file-upload #rails-activestorage Attach ActiveStorage blob with a different filename

Bounty: 100

I am looking for the most elegant way of attaching/duplicating an ActiveStorage blob with a different name.

My current best solution is using the IO interface and downloading and re-uploading the file which seems rather inefficient.

url = Rails.application.routes.url_helpers.rails_blob_url( contract.document )
attachements.push([
  io: open( path_url ),
  filename: "New contract filename"
])

I know you can do this, which is only touching the database:

contract.attach( contract.document.blob )

But I need to change the filename.

The ActiveStorage documentation seems to be spotty on this subject and I couldn’t really find what I was looking for.


Get this bounty!!!

#StackBounty: #ruby-on-rails #database-design #activeadmin #formtastic Rails 6: design database for Police's Fines

Bounty: 100

Using Rails 6, I am designing an application for manage police fines.
A user can violate many articles, an article can have many letters and a letter can have many commas.

This is my implementations:

#models/fine.rb
class Fine < ApplicationRecord
  has_many :violations
  has_many :articles, through: :violations
  has_many :letters, through: :violations
  has_many :commas, through: :violations
end
#models/article.rb
class Article < ApplicationRecord
  has_many :letters
  has_many :violations
  has_many :fines, through: :violations
end
#models/letter.rb
class Letter < ApplicationRecord
  belongs_to :article
  has_many :commas

  has_many :violations
  has_many :fines, through: :violations

end
#models/comma.rb
class Comma < ApplicationRecord
  belongs_to :letter

  has_many :violations
  has_many :fines, through: :violations
end
#models/violation.rb
class Violation < ApplicationRecord
  belongs_to :fine

  belongs_to :article
  belongs_to :letter, optional: true
  belongs_to :comma, optional: true
end

When I print the Fine in pdf I need to show violations: articles, letters and commas.

I have some difficult creating form to compile the Fine with articles,letters,commas becouse is too deep.

I am using Active Admin, when I create new Fine I want to associate many violations.

Violation example:

Violation.new
 => #<Violation id: nil, article_id: nil, fine_id: nil, letter_id: nil, comma_id: nil, note: nil, created_at: nil, updated_at: nil> 

How can I create a form (using Active Admin, who use Formtastic) to associate many violations to a Fine?

Example form: when create new Fine I want associate articles, letters and commas:

enter image description here

Example (with sample data):

Violation.new fine: fine, article: a, letter: a.letters.last, comma: a.letters.second.commas.last
 => #<Violation id: nil, article_id: 124, fine_id: 66, letter_id: 10, comma_id: 4, note: nil, created_at: nil, updated_at: nil> 


Get this bounty!!!

#StackBounty: #ruby-on-rails #ruby #ruby-on-rails-6 #paper-trail-gem #ruby-2.6 Papertrail: records with nil whodunnit values and object…

Bounty: 50

I’ve set papertrail to only record changes containing a whodunnit value/when an admin makes a change by using the below condition in my model:

has_paper_trail if: proc { |model| PaperTrail.request.whodunnit.present? }

However I’ve noticed there are still a decent amount of records being stored with empty whodunnit values. From having a look at the records, these seem to be mostly ‘update’ actions all having empty object changes for some reason. I am unsure as to why the value is empty, or how it would get saved at all considering the above condition.

I am getting whodunnit values from warden in my application controller using:

def user_for_paper_trail
  request.env['warden']&.user(:admin)&.id
end

Has anyone come across similar behaviour before?


Get this bounty!!!