Gem thumbs_up shorthand syntax issue - ruby-on-rails

In thumbs_up documentation there is Shorthand Syntax section.
...
voter.vote(voteable, vote)
...
What's a vote that is coming as a second parameter there? How could I define it or where from I could get it?

vote is a option hash.
voter.vote(voteable, direction: :down) would be a downvote.
&
voter.vote(voteable, direction: :up) would be a upvote. `
EDIT:
The documentation seems to have some differences with the code :P

It seems the documentation for vote was incorrect and I've submitted a PR to fix this https://github.com/bouchard/thumbs_up/pull/104
vote takes a second argument which is a hash of options. The direction key of the hash is a required key which needs to have a value of :up or :down.

You can find it in the source code. It's a Hash of options.
This method seems to be the base utility function for the various vote helpers. You should probably use vote_for.

Related

What is map(&:id) in Rails?

My question is not an error, it is for understanding. As I'm new to Rails, I can't read all the code yet.
what does (&:id) do after .map
#user_cnae_classifications = user.cnae_classifications.map(&:id)
what is the difference of .map with it and without it?
in this method call:
UserCnaeClassification.create(
user: #user,
cnae_classification_id: id
)
How do I read that part of the code...
user: #user,
cnae_classification_id: id
are they keys and values?
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 (&:id) do after .map
The syntax map(&:method) is equivalent to:
object.map do |i|
i.method
end
The complete explanation is that the & operator is used to convert any Ruby object that responds to to_proc into a Proc, which encapsulates a block of code. In this case, the Symbol object (:id) is converted into the block of code above.
If you're interested in learning more about it, notice this is pure Ruby, not Rails-specific. Check the documentation for Proc.
In this method call:
How do I read that part of the code...
are they keys and values?
These are keyword arguments. It's a way to name the parameters of a method to explicitly tell the reader what each value should be. Just be aware that the behavior of methods accepting hashes as keyword arguments is deprecated, as seen in this official post.
The .map(&:id) is a shorthand for the longer form of .map { |x| x.id }.
Some interesting things to say: if you're using database (ORM - ActiveRecord), you will see that writing map(&:id) could be helpful. There also exists method called pluck, which does similiar things, but it's a little faster.
Usage:
Also pluck doesn't work with regular Arrays.

Rails to_param - Without ID

I want to create param /users/will-smith, so here's my code:
def to_param
"#{full_name.parameterize}"
end
Parameterize will convert "Will Smith" to "will-smith"
So in the controller, the param won't match the find statement, thus return nil
# User with full_name "will-smith" not found
#user = User.find_by_full_name(params[:id])
Most of the solutions I found is by changing the param to #{id}-#{full_name.parameterize}. But I don't want the URL to contain the ID.
The other solutions is adding permalink column in the database, which I don't really like.
Any other solution?
Thanks
Here's a gem called FriendlyId. It will give you more options to play with.
The problem with your code is that you need to convert that parameter back to original, or use the same kind of transformation on your column during the search. FriendlyId, basically, helps you to achieve the same effect.
Also, I'm not sure, but you could miss that gist. It contaits lots of info on the topic.

Understanding will_paginate arguments

Total Rails noob, working through the Rails Tutorial videos. I'm all the way to the last lesson, and there's something I don't understand:
#users = #user.followed_users.paginate(page: params[:page])
Specifically, the bit I'm not tracking on is paginate(page: params[:page]). I looked at the paginate docs and I understand the paginate method can take three params, :page being one of them. I think this parameter means "current page," but the will_paginate docs say it defaults to 1.
I also know (think) that params[:page] refers to the built-in Rails params hash, meaning, current session params. Right?
So... I don't get it. Why do I need it? How does the :page symbol get into the params hash? What does this really do?
For additional context, see listing 11.30 on the Ruby Tutorial book. Any help would be much appreciated.
I think what you might be misunderstanding is how Ruby arguments work in this case. paginate does not actually take 3 arguments, but instead takes a single hash argument with three options (key/value pairs).
In Ruby, when you pass key/value pairs as the last set of arguments, they are automatically converted to a hash. For example, the following are equivalent:
paginate({page: 1})
is the same as:
paginate(page: 1)
So really what you are doing is passing a single argument, which is a hash that has multiple key/value pairs.
Now to specifically answer your questions:
Why do I need it?
You need to pass this value in so that will_paginate knows which page you are currently on. It defaults to page one because on the initial page load, you will not have ?page=x in your URL. After you change to a different page, it takes the page value from the URL and passes that to the paginate method.
How does the :page symbol get into the params hash?
Any argument that is part of the query params in the URL will get automatically passed to the params hash by Rails (more likely Rack which Rails is built upon)
What does this really do?
I'm hoping the above answered this, but if not, maybe it provided you with enough info to come up with a more specific question.

options.fetch . I don't get it

Look at the discussion on this thread . I am not able to follow how having a block to a fetch is a better solution.
In the first patch on Rails ticket #4558:
options.fetch(:alt, File.basename(src, '.*').capitalize)
This line executes the basename and capitalize functions and then passes the result into Hash#fetch regardless of if a value for :alt already exists in the options hash.
In the updated patch:
options.fetch(:alt) { File.basename(src, '.*').capitalize }
The same basename/capitalize code is only executed when Hash#fetch needs the default value (i.e. when the :alt key does not exist in the options hash). This means the (possibly expensive) calculation of the default value can be skipped if it's not needed.
See the documentation on Hash#fetch for more details.
I don't know what duck-punching Rails has been doing to Hash#fetch, but with Plain Old Ruby Objects, I use it rather than Hash#[] because when I ask for something and it's not available, I want to know about it. This is called "Failing early" (or "Crashing early" in The Pragmatic Programmer's List of Tips)

Groovy "except" syntax?

I am a total Groovy newbie. I saw the following code here.
def beforeInterceptor = [action:this.&auth,except:'login']
How would I expand this to also include a second exception, say, if the action was 'login2'?
Wow, would have expected a quick answer on this!
Well, found my own answer: you can't have more than one exception with except.
See the feature request here.
Instead, they recommend creating a Filter. See here.

Resources