Rails class method used as scope with complex logic
In the system there are employees with login information in the User model and
other information about them in the Profile model.
We want to be able to display a list of employees who have an anniversary
this month (the month of hire is the same as the current one) and it is
their 1st, 2nd, or a multiple of 5 years on the job.
We want to use it like a scope, but since the logic is complex, we are making
a Class method. Trying to split the logic into small chunks is becoming messy.
I am sure that the code can be simplified.
The biggest issue is that instead of getting a list of only the employees with
an anniversary as a scope would do, I am getting a list of all the employees
as nil or their user info if it is their anniversary month.
An example:
irb_001 >> Profile.anniversary?
[
[0] nil,
[1] nil,
[2] #<User:0x007fd17c883740> {
:id => 3,
:first_name => "Sally",
:last_name => "Brown",
:email => "sally@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 21 Feb 2018 11:12:42 EST -05:00,
:updated_at => Sat, 25 Feb 2018 12:28:45 EST -05:00,
},
[3] nil,
[4] nil,
[5] #<User:0x007fd17a2eaf38> {
:id => 6,
:first_name => "Lucy",
:last_name => "Van Pelt",
:email => "lucy@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 20 Nov 2018 21:01:04 EST -05:00,
:updated_at => Tue, 20 Nov 2018 21:02:36 EST -05:00,
},
[6] nil
]
irb_002 >>
What is the best way to achieve the desired result and clean up this code?
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, allow_destroy: true
after_create :create_matching_profile
delegate :active, to: :profile, prefix: true
private
def create_matching_profile
profile = build_profile
profile.save
end
end
class Profile < ActiveRecord::Base
belongs_to :user
def self.years_employed(profile)
# calculate how many years employed
@profile = profile
if @profile.employed_since?
(( Date.today.to_time - @profile.employed_since.to_time )/1.year.second).to_i
else
0
end
end
def self.anniversary_month(profile)
# get the month of hire
@profile = profile
@profile.employed_since? ? @profile.employed_since.month : 0
end
def self.anniversary?
# first, second, or multiple of five year anniversary month
@profiles = Profile.where("employed_since is not null")
@profiles.map do |profile|
if ( Date.today.month == anniversary_month(profile) )
@years_working = years_employed(profile)
if ( @years_working> 0 &&
( @years_working == 1 || @years_working == 2 || ( @years_working % 5 == 0 )))
result = true
else
result = false
end
else
result = false
end
profile.user if result
end
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# email :string
# password_digest :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Table name: profiles
#
# id :integer not null, primary key
# user_id :integer
# active :boolean
# employed_since :date
# ...other attributes...
# created_at :datetime not null
# updated_at :datetime not null
#
employed since data from Profiles
[
[0] Sun, 01 Dec 1991,
[1] Thu, 01 May 2018,
[2] Wed, 01 Nov 2017,
[3] Wed, 01 Feb 2017,
[4] Thu, 01 Aug 2018,
[5] Fri, 01 Nov 2013,
[6] Fri, 01 Nov 1991
]
ruby-on-rails ruby-on-rails-4 scope class-method named-scope
add a comment |
In the system there are employees with login information in the User model and
other information about them in the Profile model.
We want to be able to display a list of employees who have an anniversary
this month (the month of hire is the same as the current one) and it is
their 1st, 2nd, or a multiple of 5 years on the job.
We want to use it like a scope, but since the logic is complex, we are making
a Class method. Trying to split the logic into small chunks is becoming messy.
I am sure that the code can be simplified.
The biggest issue is that instead of getting a list of only the employees with
an anniversary as a scope would do, I am getting a list of all the employees
as nil or their user info if it is their anniversary month.
An example:
irb_001 >> Profile.anniversary?
[
[0] nil,
[1] nil,
[2] #<User:0x007fd17c883740> {
:id => 3,
:first_name => "Sally",
:last_name => "Brown",
:email => "sally@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 21 Feb 2018 11:12:42 EST -05:00,
:updated_at => Sat, 25 Feb 2018 12:28:45 EST -05:00,
},
[3] nil,
[4] nil,
[5] #<User:0x007fd17a2eaf38> {
:id => 6,
:first_name => "Lucy",
:last_name => "Van Pelt",
:email => "lucy@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 20 Nov 2018 21:01:04 EST -05:00,
:updated_at => Tue, 20 Nov 2018 21:02:36 EST -05:00,
},
[6] nil
]
irb_002 >>
What is the best way to achieve the desired result and clean up this code?
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, allow_destroy: true
after_create :create_matching_profile
delegate :active, to: :profile, prefix: true
private
def create_matching_profile
profile = build_profile
profile.save
end
end
class Profile < ActiveRecord::Base
belongs_to :user
def self.years_employed(profile)
# calculate how many years employed
@profile = profile
if @profile.employed_since?
(( Date.today.to_time - @profile.employed_since.to_time )/1.year.second).to_i
else
0
end
end
def self.anniversary_month(profile)
# get the month of hire
@profile = profile
@profile.employed_since? ? @profile.employed_since.month : 0
end
def self.anniversary?
# first, second, or multiple of five year anniversary month
@profiles = Profile.where("employed_since is not null")
@profiles.map do |profile|
if ( Date.today.month == anniversary_month(profile) )
@years_working = years_employed(profile)
if ( @years_working> 0 &&
( @years_working == 1 || @years_working == 2 || ( @years_working % 5 == 0 )))
result = true
else
result = false
end
else
result = false
end
profile.user if result
end
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# email :string
# password_digest :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Table name: profiles
#
# id :integer not null, primary key
# user_id :integer
# active :boolean
# employed_since :date
# ...other attributes...
# created_at :datetime not null
# updated_at :datetime not null
#
employed since data from Profiles
[
[0] Sun, 01 Dec 1991,
[1] Thu, 01 May 2018,
[2] Wed, 01 Nov 2017,
[3] Wed, 01 Feb 2017,
[4] Thu, 01 Aug 2018,
[5] Fri, 01 Nov 2013,
[6] Fri, 01 Nov 1991
]
ruby-on-rails ruby-on-rails-4 scope class-method named-scope
you can add a.compact
at the end of themap
block inside the method so it removesnil
values (like:map do ..... end.compact
), or useselect
method instead ofmap
– arieljuod
Nov 25 '18 at 2:35
1
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37
add a comment |
In the system there are employees with login information in the User model and
other information about them in the Profile model.
We want to be able to display a list of employees who have an anniversary
this month (the month of hire is the same as the current one) and it is
their 1st, 2nd, or a multiple of 5 years on the job.
We want to use it like a scope, but since the logic is complex, we are making
a Class method. Trying to split the logic into small chunks is becoming messy.
I am sure that the code can be simplified.
The biggest issue is that instead of getting a list of only the employees with
an anniversary as a scope would do, I am getting a list of all the employees
as nil or their user info if it is their anniversary month.
An example:
irb_001 >> Profile.anniversary?
[
[0] nil,
[1] nil,
[2] #<User:0x007fd17c883740> {
:id => 3,
:first_name => "Sally",
:last_name => "Brown",
:email => "sally@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 21 Feb 2018 11:12:42 EST -05:00,
:updated_at => Sat, 25 Feb 2018 12:28:45 EST -05:00,
},
[3] nil,
[4] nil,
[5] #<User:0x007fd17a2eaf38> {
:id => 6,
:first_name => "Lucy",
:last_name => "Van Pelt",
:email => "lucy@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 20 Nov 2018 21:01:04 EST -05:00,
:updated_at => Tue, 20 Nov 2018 21:02:36 EST -05:00,
},
[6] nil
]
irb_002 >>
What is the best way to achieve the desired result and clean up this code?
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, allow_destroy: true
after_create :create_matching_profile
delegate :active, to: :profile, prefix: true
private
def create_matching_profile
profile = build_profile
profile.save
end
end
class Profile < ActiveRecord::Base
belongs_to :user
def self.years_employed(profile)
# calculate how many years employed
@profile = profile
if @profile.employed_since?
(( Date.today.to_time - @profile.employed_since.to_time )/1.year.second).to_i
else
0
end
end
def self.anniversary_month(profile)
# get the month of hire
@profile = profile
@profile.employed_since? ? @profile.employed_since.month : 0
end
def self.anniversary?
# first, second, or multiple of five year anniversary month
@profiles = Profile.where("employed_since is not null")
@profiles.map do |profile|
if ( Date.today.month == anniversary_month(profile) )
@years_working = years_employed(profile)
if ( @years_working> 0 &&
( @years_working == 1 || @years_working == 2 || ( @years_working % 5 == 0 )))
result = true
else
result = false
end
else
result = false
end
profile.user if result
end
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# email :string
# password_digest :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Table name: profiles
#
# id :integer not null, primary key
# user_id :integer
# active :boolean
# employed_since :date
# ...other attributes...
# created_at :datetime not null
# updated_at :datetime not null
#
employed since data from Profiles
[
[0] Sun, 01 Dec 1991,
[1] Thu, 01 May 2018,
[2] Wed, 01 Nov 2017,
[3] Wed, 01 Feb 2017,
[4] Thu, 01 Aug 2018,
[5] Fri, 01 Nov 2013,
[6] Fri, 01 Nov 1991
]
ruby-on-rails ruby-on-rails-4 scope class-method named-scope
In the system there are employees with login information in the User model and
other information about them in the Profile model.
We want to be able to display a list of employees who have an anniversary
this month (the month of hire is the same as the current one) and it is
their 1st, 2nd, or a multiple of 5 years on the job.
We want to use it like a scope, but since the logic is complex, we are making
a Class method. Trying to split the logic into small chunks is becoming messy.
I am sure that the code can be simplified.
The biggest issue is that instead of getting a list of only the employees with
an anniversary as a scope would do, I am getting a list of all the employees
as nil or their user info if it is their anniversary month.
An example:
irb_001 >> Profile.anniversary?
[
[0] nil,
[1] nil,
[2] #<User:0x007fd17c883740> {
:id => 3,
:first_name => "Sally",
:last_name => "Brown",
:email => "sally@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 21 Feb 2018 11:12:42 EST -05:00,
:updated_at => Sat, 25 Feb 2018 12:28:45 EST -05:00,
},
[3] nil,
[4] nil,
[5] #<User:0x007fd17a2eaf38> {
:id => 6,
:first_name => "Lucy",
:last_name => "Van Pelt",
:email => "lucy@peanuts.com",
:password_digest => "[redacted]",
:created_at => Tue, 20 Nov 2018 21:01:04 EST -05:00,
:updated_at => Tue, 20 Nov 2018 21:02:36 EST -05:00,
},
[6] nil
]
irb_002 >>
What is the best way to achieve the desired result and clean up this code?
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, allow_destroy: true
after_create :create_matching_profile
delegate :active, to: :profile, prefix: true
private
def create_matching_profile
profile = build_profile
profile.save
end
end
class Profile < ActiveRecord::Base
belongs_to :user
def self.years_employed(profile)
# calculate how many years employed
@profile = profile
if @profile.employed_since?
(( Date.today.to_time - @profile.employed_since.to_time )/1.year.second).to_i
else
0
end
end
def self.anniversary_month(profile)
# get the month of hire
@profile = profile
@profile.employed_since? ? @profile.employed_since.month : 0
end
def self.anniversary?
# first, second, or multiple of five year anniversary month
@profiles = Profile.where("employed_since is not null")
@profiles.map do |profile|
if ( Date.today.month == anniversary_month(profile) )
@years_working = years_employed(profile)
if ( @years_working> 0 &&
( @years_working == 1 || @years_working == 2 || ( @years_working % 5 == 0 )))
result = true
else
result = false
end
else
result = false
end
profile.user if result
end
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# email :string
# password_digest :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Table name: profiles
#
# id :integer not null, primary key
# user_id :integer
# active :boolean
# employed_since :date
# ...other attributes...
# created_at :datetime not null
# updated_at :datetime not null
#
employed since data from Profiles
[
[0] Sun, 01 Dec 1991,
[1] Thu, 01 May 2018,
[2] Wed, 01 Nov 2017,
[3] Wed, 01 Feb 2017,
[4] Thu, 01 Aug 2018,
[5] Fri, 01 Nov 2013,
[6] Fri, 01 Nov 1991
]
ruby-on-rails ruby-on-rails-4 scope class-method named-scope
ruby-on-rails ruby-on-rails-4 scope class-method named-scope
asked Nov 25 '18 at 1:12
MERMMERM
383312
383312
you can add a.compact
at the end of themap
block inside the method so it removesnil
values (like:map do ..... end.compact
), or useselect
method instead ofmap
– arieljuod
Nov 25 '18 at 2:35
1
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37
add a comment |
you can add a.compact
at the end of themap
block inside the method so it removesnil
values (like:map do ..... end.compact
), or useselect
method instead ofmap
– arieljuod
Nov 25 '18 at 2:35
1
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37
you can add a
.compact
at the end of the map
block inside the method so it removes nil
values (like: map do ..... end.compact
), or use select
method instead of map
– arieljuod
Nov 25 '18 at 2:35
you can add a
.compact
at the end of the map
block inside the method so it removes nil
values (like: map do ..... end.compact
), or use select
method instead of map
– arieljuod
Nov 25 '18 at 2:35
1
1
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37
add a comment |
2 Answers
2
active
oldest
votes
This can be done in a much simpler and more efficient way by using the date functions in the database and doing the comparison there.
class User < ApplicationRecord
has_one :profile
def self.anniversary
self.joins(:profile)
.where("EXTRACT(MONTH FROM profiles.employed_since) = EXTRACT(MONTH FROM now())")
.where("profiles.employed_since < ?", 1.year.ago)
.where(%q{
EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since BETWEEN 1 AND 2
OR
CAST(EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since) AS INTEGER) % 5 = 0
})
end
end
This example is written for Postgres and you might need to adapt it to your RDBMS.
add a comment |
Using SQLITE the where clause looks like:
where "strftime('%m',employed_since) = strftime('%m', date('now'))
AND employed_since < date('now','-1 year','+1 day')
AND ( (strftime('%Y','now') - strftime('%Y', employed_since)) BETWEEN 1 AND 2
OR (strftime('%Y','now') - strftime('%Y', employed_since)) % 5 = 0 )"
This actually works as a scope, no need for a class method as I originally thought.
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.
– max
Dec 3 '18 at 11:25
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463854%2frails-class-method-used-as-scope-with-complex-logic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This can be done in a much simpler and more efficient way by using the date functions in the database and doing the comparison there.
class User < ApplicationRecord
has_one :profile
def self.anniversary
self.joins(:profile)
.where("EXTRACT(MONTH FROM profiles.employed_since) = EXTRACT(MONTH FROM now())")
.where("profiles.employed_since < ?", 1.year.ago)
.where(%q{
EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since BETWEEN 1 AND 2
OR
CAST(EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since) AS INTEGER) % 5 = 0
})
end
end
This example is written for Postgres and you might need to adapt it to your RDBMS.
add a comment |
This can be done in a much simpler and more efficient way by using the date functions in the database and doing the comparison there.
class User < ApplicationRecord
has_one :profile
def self.anniversary
self.joins(:profile)
.where("EXTRACT(MONTH FROM profiles.employed_since) = EXTRACT(MONTH FROM now())")
.where("profiles.employed_since < ?", 1.year.ago)
.where(%q{
EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since BETWEEN 1 AND 2
OR
CAST(EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since) AS INTEGER) % 5 = 0
})
end
end
This example is written for Postgres and you might need to adapt it to your RDBMS.
add a comment |
This can be done in a much simpler and more efficient way by using the date functions in the database and doing the comparison there.
class User < ApplicationRecord
has_one :profile
def self.anniversary
self.joins(:profile)
.where("EXTRACT(MONTH FROM profiles.employed_since) = EXTRACT(MONTH FROM now())")
.where("profiles.employed_since < ?", 1.year.ago)
.where(%q{
EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since BETWEEN 1 AND 2
OR
CAST(EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since) AS INTEGER) % 5 = 0
})
end
end
This example is written for Postgres and you might need to adapt it to your RDBMS.
This can be done in a much simpler and more efficient way by using the date functions in the database and doing the comparison there.
class User < ApplicationRecord
has_one :profile
def self.anniversary
self.joins(:profile)
.where("EXTRACT(MONTH FROM profiles.employed_since) = EXTRACT(MONTH FROM now())")
.where("profiles.employed_since < ?", 1.year.ago)
.where(%q{
EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since BETWEEN 1 AND 2
OR
CAST(EXTRACT(year FROM now()) - EXTRACT(year FROM profiles.employed_since) AS INTEGER) % 5 = 0
})
end
end
This example is written for Postgres and you might need to adapt it to your RDBMS.
edited Nov 25 '18 at 6:21
answered Nov 25 '18 at 4:31
maxmax
46.2k1060104
46.2k1060104
add a comment |
add a comment |
Using SQLITE the where clause looks like:
where "strftime('%m',employed_since) = strftime('%m', date('now'))
AND employed_since < date('now','-1 year','+1 day')
AND ( (strftime('%Y','now') - strftime('%Y', employed_since)) BETWEEN 1 AND 2
OR (strftime('%Y','now') - strftime('%Y', employed_since)) % 5 = 0 )"
This actually works as a scope, no need for a class method as I originally thought.
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.
– max
Dec 3 '18 at 11:25
add a comment |
Using SQLITE the where clause looks like:
where "strftime('%m',employed_since) = strftime('%m', date('now'))
AND employed_since < date('now','-1 year','+1 day')
AND ( (strftime('%Y','now') - strftime('%Y', employed_since)) BETWEEN 1 AND 2
OR (strftime('%Y','now') - strftime('%Y', employed_since)) % 5 = 0 )"
This actually works as a scope, no need for a class method as I originally thought.
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.
– max
Dec 3 '18 at 11:25
add a comment |
Using SQLITE the where clause looks like:
where "strftime('%m',employed_since) = strftime('%m', date('now'))
AND employed_since < date('now','-1 year','+1 day')
AND ( (strftime('%Y','now') - strftime('%Y', employed_since)) BETWEEN 1 AND 2
OR (strftime('%Y','now') - strftime('%Y', employed_since)) % 5 = 0 )"
This actually works as a scope, no need for a class method as I originally thought.
Using SQLITE the where clause looks like:
where "strftime('%m',employed_since) = strftime('%m', date('now'))
AND employed_since < date('now','-1 year','+1 day')
AND ( (strftime('%Y','now') - strftime('%Y', employed_since)) BETWEEN 1 AND 2
OR (strftime('%Y','now') - strftime('%Y', employed_since)) % 5 = 0 )"
This actually works as a scope, no need for a class method as I originally thought.
answered Dec 1 '18 at 19:52
MERMMERM
383312
383312
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.
– max
Dec 3 '18 at 11:25
add a comment |
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.
– max
Dec 3 '18 at 11:25
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.– max
Dec 3 '18 at 11:25
scope
is really just syntactic sugar that declares a class method so there is no actual difference. From a readability standpoint its better to declare a standard class method for multi-line methods though.– max
Dec 3 '18 at 11:25
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463854%2frails-class-method-used-as-scope-with-complex-logic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
you can add a
.compact
at the end of themap
block inside the method so it removesnil
values (like:map do ..... end.compact
), or useselect
method instead ofmap
– arieljuod
Nov 25 '18 at 2:35
1
This could no doubt be done much more effectively by using the date functions in the DB to extract the month/year from the timestamp and doing the comparison in the DB instead of by pulling out all the records which is not viable as the data size increases.
– max
Nov 25 '18 at 2:37