What does Post.all.map(&:id) mean?
The &
symbol is used to denote that the following argument should be treated as the block given to the method. That means that if it's not a Proc object yet, its to_proc
method will be called to transform it into one.
Thus, your example results in something like
Post.all.map(&:id.to_proc)
which in turn is equivalent to
Post.all.map { |x| x.id }
So it iterates over the collection returned by Post.all
and builds up an array with the result of the id
method called on every item.
This works because Symbol#to_proc
creates a Proc that takes an object and calls the method with the name of the symbol on it. It's mainly used for convenience, to save some typing.
What exactly does (&:id) do in Product.all.map(&:id)
Category.all.map(&:id)
is shorthand for
Category.all.map { |a| a.id }
as for how it affects the rest of the line, the above section returns all id
values as a single Array
. This Array
of ids is then passed into another call to each
, which iteratively passes each id into reset_counters
.
What is map(&:id) in Rails?
1 )
You should read some tutorials on map
to get acquainted.
https://www.rubyguides.com/2018/10/ruby-map-method
But the short answer is that running user.cnae_classifications.map(&:id)
will loop over all cnae_classifications
and extract the id
from them and put them all into an array. The &
character allows for map
shorthand to avoid passing an entire block.
From the link above:
2 )
The #create
method can accept a key-value hash of known attributes (known to the class in question, in this case that is UserCnaeClassification
) to assign upon creation. So you're basically right, they are key-value pairs but they are specific to this class/object. Those same keys might not work on another class/object.
Additional reading: https://guides.rubyonrails.org/active_record_basics.html#create
What does map(&:name) mean in Ruby?
It's shorthand for tags.map(&:name.to_proc).join(' ')
If foo
is an object with a to_proc
method, then you can pass it to a method as &foo
, which will call foo.to_proc
and use that as the method's block.
The Symbol#to_proc
method was originally added by ActiveSupport but has been integrated into Ruby 1.8.7. This is its implementation:
class Symbol
def to_proc
Proc.new do |obj, *args|
obj.send self, *args
end
end
end
wp_category map: id & name
$post_categories = [];
array_walk(array_filter($categories, function ($cat) {
// exclude 21 & 1
return $cat->term_id !== 21 && $cat->term_id !== 1;
}, ARRAY_FILTER_USE_BOTH),
function ($fiteredCat) use(&$post_categories){
$post_categories[$fiteredCat->term_id] = $fiteredCat->cat_name;
});
echo json_encode(['post_categories' => $post_categories]);
map(&:id) work but not pluck(:id)
This line:
users_to_remove = self.users.where(id: user_ids)
Doesn't fire off SQL query immediately. It sends the request whenever you need some details of these users. And it caches the result in SQL cache (so when the same request goes to DB again, it intercepted by Rails and never reaches the database).
So when you call:
users_to_remove.map(&:id)
It uses that cached result. But when you use
users_to_remove.pluck(:id)
It re-fetches the result, because the actual SQL query differs. With #map
it is SELECT * FROM ...
, and with #pluck
it's SELECT id FROM...
. And when query reaches the database, IDs doesn't belong to 'self' any longer (you deleted them right before that), so they aren't returned.
What does the map method do in Ruby?
The map
method takes an enumerable object and a block, and runs the block for each element, outputting each returned value from the block (the original object is unchanged unless you use map!)
:
[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]
Array
and Range
are enumerable types. map
with a block returns an Array. map!
mutates the original array.
Where is this helpful, and what is the difference between map!
and each
? Here is an example:
names = ['danil', 'edmund']
# here we map one array to another, convert each element by some rule
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']
names.each { |name| puts name + ' is a programmer' } # here we just do something with each element
The output:
Danil is a programmer
Edmund is a programmer
Get all ids from a collection
What about trying hotels.map(&:id)
or hotels.map{|h| h.id }
?
They both mean the same thing to Ruby, the first one is nicer to accustomed ruby-ists usually, whilst the second one is easier to understand for beginners.
Related Topics
Scope of Constants in Ruby Modules
How to Use Unicorn as "Rails S"
Tell the End of a .Each Loop in Ruby
Gem Install Pg Can Not Bind to Libpq
Empty Attribute with Ruby Haml
Run Ruby Script in Elevated Mode
Properly Converting a Cmyk Image to Rgb with Rmagick
Rails - Multiple Top Level Domains and a Single Session/Cookie
Visit_Psych_Nodes_Alias: Unknown Alias: Default (Psych::Badalias)
Selenium Rc: Run Tests in Multiple Browsers Automatically
How to Sort a String's Characters Alphabetically
Create Array of N Items Based on Integer Value
Writing Over Previously Output Lines in the Command Prompt with Ruby
Dynamically Creating a Multi-Dimensional Hash in Ruby
Difference Between 'Self.Method_Name' and 'Class << Self' in Ruby