-
Notifications
You must be signed in to change notification settings - Fork 0
Useful Methods
- merge
class Catalog < ApplicationRecord
has_many :channels, through: :channel_catalogs
end
class Channel < ApplicationRecord
has_many :catalogs, through: :channel_catalogs
end
channel = Channel.last
channel.catalogs = Catalog.first(2)
# レコードがある時は、同じ挙動。
Channel.find_by(id: 17).catalogs.pluck(:id)
=> [1, 2]
Catalog.joins(:channels).merge(Channel.where(id: 17)).pluck(:id)
=> [1, 2]
# レコードが無い時に、挙動が変わる。nilの時にNoMethodErrorになるか、[]が返るか。
Channel.find_by(id: 100).catalogs.pluck(:id)
=> NoMethodError: undefined method `catalogs' for nil:NilClass
Channel.find_by(id: 100)&.catalogs&.pluck(:id)
=> nil
Catalog.joins(:channels).merge(Channel.where(id: 100)).pluck(:id)
=> []
# 期待動作する時のSQL
> Catalog.joins(:channels).merge(Channel.where(id: 17)).to_sql
=> "SELECT `catalogs`.* FROM `catalogs` INNER JOIN `channel_catalogs` ON `channel_catalogs`.`catalog_id` = `catalogs`.`id` AND (`channel_catalogs`.`request_status` = 20 OR `channel_catalogs`.`request_status` IS NULL) INNER JOIN `channels` ON `channels`.`id` = `channel_catalogs`.`channel_id` WHERE `channels`.`id` = 17"
# 期待動作しない時のSQL
> Channel.joins(:fairs).merge(Fair.where(id: 17)).to_sql
=> "SELECT `channels`.* FROM `channels` INNER JOIN `channel_fairs` ON `channel_fairs`.`channel_id` = `channels`.`id` INNER JOIN `channels` `fairs_channels` ON `fairs_channels`.`id` = `channel_fairs`.`fair_id` AND `fairs_channels`.`type` IN ('Fair') WHERE `channels`.`type` IN ('Fair') AND `channels`.`id` = 17"There're lots of useful methods that are enhanced by ActiveSupport. You should check the following site, too.
http://guides.rubyonrails.org/active_support_core_extensions.html
- &
It's same as
try!
-
try
-
nil?
-
empty?
-
blank?
-
present?
-
presence
-
yield
-
yield_self (Ruby 2.5)
-
then (Ruby 2.6) alias of
yield_self(discussion) -
block_given?
-
each
-
each_with_index
-
map
Get used to the following syntax (e.g.):
%w[a b c].map(&:upcase)Use
mapwhen you want to get an array. Otherwise, useeach. Differentiate them. -
each_with_object (Rubocop suggests using each_with_object instead of
reduce/inject)
def self.providers
{
email: {
formal: 'Email',
id: 'email'
},
facebook: {
formal: 'Facebook',
id: 'facebook.com'
}
}.with_indifferent_access
end
> ExternalAccount.providers.reduce({}) { |h, (k, v)| h[v[:id]] = k; h }
=> {"email"=>"email", "facebook.com"=>"facebook"}
> ExternalAccount.providers.each_with_object({}) { |(k, v), h | h[v[:id]] = k }
=> {"email"=>"email", "facebook.com"=>"facebook"}-
keys
-
values
-
size (instead of length and count)
-
flatten
-
exists? (See the difference between exists?, present? and any? here)
User.exists?(email: 'test@example.com')
User Exists (2.5ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "test@example.com"], ["LIMIT", 1]]
=> true
User.where(email: 'test@example.com').exists?
User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "test@example.com"], ["LIMIT", 1]]
=> true- any?
- all?
['foo', 'bar'].all?(&:blank?)
=> false
['foo', ''].all?(&:blank?)
=> false
['', ''].all?(&:blank?)
=> true
[nil, ''].all?(&:blank?)
=> true-
pluck
-
find_each
-
find_in_batches
-
first (this doesn't work when id is uuid)
-
last (the same as above)
-
include?
[1, 2, 3].include?(3)
=> true
(0...10).include?(3)
=> true
(0...10).include?(10)
=> false- in?
(3).in?([1,2,3])
=> true
(3).in?(0...10)
=> true
(10).in?(0...10)
=> false-
values_at
-
fetch_values
-
slice
-
except
-
merge
-
select
-
reject
-
dig
-
match
-
to_param
-
to_query
-
start_with?
-
end_with?
-
symbolize_keys (deep_symbolize_keys)
-
stringify_keys (deep_stringify_keys)
-
send (public_send)
-
define_method
-
tap
-
attributes
user.attributes = { name: 'myname', email: 'myname@example.com' }-
assign_attributes
-
delegate
-
html_safe
-
squish
-
inquiry
-
strip_heredoc
-
*
[*1..5]
=> [1, 2, 3, 4, 5]a, *b = [1, 2 ,3]
=> [1, 2, 3]
b
=> [2, 3]- rjust
The following methods written here.
- any?
- blank?
- build
- create, create!
- delete_all
- destroy_all
- empty?
- explain
- find_or_create_by, find_or_create_by!
Job.find(1000)
=> ActiveRecord::RecordNotFound: Couldn't find Job with 'id'=1000
job = Job.find_or_create_by(id: 1000) do |j|
j.id_token = 'new_id_token'
end
job.new_record?
=> true
job.id_token
=> "new_id_token"- find_or_initialize_by
- new
- reload
- size
- to_sql
- update_all
- redirect_to post_url(@post) and return
https://api.rubyonrails.org/classes/ActionController/Redirecting.html
- ActiveRecord で オブジェクト同士を==で比較した場合、id を比較している
-
helper_method
-
module_function
-
with_indifferent_access
providers = {
facebook: {
formal: 'Facebook',
id: 'facebook.com'
}
}.with_indifferent_access
> providers[:facebook]
=> {
"formal" => "Facebook",
"id" => "facebook.com"
}
> providers['facebook']
=> {
"formal" => "Facebook",
"id" => "facebook.com"
}