How to Handle Method Order in Ruby

How to handle Method Order in Ruby?

You can not call a method before you define it. However, that does not mean you can't define myfunction before myfunction2! Ruby has late binding, so the call to myfunction2 in myfunction will not be associated with the actual myfunction2 before you call myfunction. That means that as long as the first call to myfunction is done after myfunction2 is declared, you should be fine.

So, this is ok:

def myfunction
myfunction2
end

def myfunction2
puts "in 2"
end

myfunction

and this is not:

def myfunction
myfunction2
end

myfunction

def myfunction2
puts "in 2"
end

Execution Order In a Method with Rails

I cannot be sure without seeing the code, but judging from the parameters you pass, I guess that FillMethods.fill_info retrieves the record from db again, using the third parameter id. It then changes the record and stores it back.

Your object (self) has no way, under ActiveRecord or similar, to know that the db was modified somewhere somehow.

Note that you are retrieving the same record from db some three times instead than once.

If you change FillMethods.fill_info to instead accept a record (self itself), and modify it, then self would be in the new state.

Addendum

Ruby code is executed sequentially in a single thread unless you explicitly start a new thread, so yes, .fill_info is executed before continuing with the rest of update_fields.

Order by output of a class method rails

The order method is writing a SQL query so it can't use a custom method like that. You would need to use ruby to do what you want.

Baker.all.sort_by(&:this_week_cookies)

Common method order for Rails models

It doesn't matter what convention you follow as long as you keep it consistent and easier for other developers to understand.

Commonly followed ordering would be

1. associations
2. scopes
3. class methods
4. validations
5. callbacks
6. instance methods

Some people also move class methods below callbacks. Again, its up to you. But keep it consistent

Ordering a collection by instance method

order from ActiveRecord similar to sort from ruby. So, Od.all.sort run iteration after the database query Od.all, run a new iteration map and then send a new database query. Also Od.all.sort has no sense because where select record when id included in ids but not searching a record for each id.

Easier do something like this:

Od.all.sort_by { |od| [od.priority, od.due_date_time] }

But that is a slow solution(ods table include 10k+ records). Prefer to save column to sort to the database. When that is not possible set logic to calculate due_date_time in a database query.

Rails 4, how to ordering using custom method

I think the answer depends on what you want to see in the view because some of the problem could actually be solved in how you call @lists there. Also, some of the links you found make sorting by a model method sound more difficult than it is.

In your case, you can sort your conversations by a custom method like so:
Conversation.all.sort_by(&:custom_method)

Or specifically:
Conversation.all.sort_by(&:last_answered_to_i)

Specifically, you cannot use SQL to sort or order by something not in the actual database, so you use the Ruby sort_by method. For more info on the ampersand, see this post.

For your actual view, I'm not sure really how you want to organize it. I recently did something where I needed to group my resource by another resource called "categories", and then sort the original resource by "netvotes" which was a custom model method, then order by name. I did it by:

  • Ordering by name in the controller: @resources = Resource.order(:name)
  • Grouping by category in the outer loop of the view: <% @resources.group_by(&:category).each do |category, resources| %>
  • Then sorting the resources by votes in the partial for resources: <%= render resources.sort_by(&:netvotes).reverse %>

The view is a bit confusing, so here is the full view loop in index.html.erb:

<% @resources.group_by(&:category).each do |category, resources| %>
<div class="well">
<h3 class="brand-text"><%= category.name %></h3>
<%= render resources.sort_by(&:netvotes).reverse %>
</div>
<% end %>

And here is the _resource.html.erb partial:

<div class="row resource">
<div class="col-sm-2 text-center">
<div class="vote-box">
<%= link_to fa_icon('chevron-up lg'), upvote_resource_path(resource), method: :put %><br>
<%= resource.netvotes %><br>
<%= link_to fa_icon('chevron-down lg'), downvote_resource_path(resource), method: :put %>
</div>
</div>
<div class="col-sm-10">
<%= link_to resource.name, resource.link, target: "_blank" %>
<p><%= resource.notes %></p>
</div>
</div>

I hope that helps you think through some more ways to address your problem.

Order a hash/array

Hey you can use Ruby sort_by as - sign is used for order using desc:

Sale.where(brand: current_user.brand).group(:product).by_day.sum(:quantity).sort_by{|product,quantity|  -quantity}

How do I test the order of method calls in rspec?

RSpec Mocks provides ordered since at least RSpec 3.0:

You can use ordered to constrain the order of multiple message expectations. This is not generally recommended because in most situations the order doesn't matter and using ordered would make your spec brittle, but it's occasionally useful. When you use ordered, the example will only pass if the messages are received in the declared order.

Note that RSpec agrees with @spickermann that this is not a recommended practice. However, there are some cases when it is necessary, especially when dealing with legacy code.

Here is RSpec's passing example:

RSpec.describe "Constraining order" do
it "passes when the messages are received in declared order" do
collaborator_1 = double("Collaborator 1")
collaborator_2 = double("Collaborator 2")

expect(collaborator_1).to receive(:step_1).ordered
expect(collaborator_2).to receive(:step_2).ordered
expect(collaborator_1).to receive(:step_3).ordered

collaborator_1.step_1
collaborator_2.step_2
collaborator_1.step_3
end
end

And failing examples:

RSpec.describe "Constraining order" do
it "fails when messages are received out of order on one collaborator" do
collaborator_1 = double("Collaborator 1")

expect(collaborator_1).to receive(:step_1).ordered
expect(collaborator_1).to receive(:step_2).ordered

collaborator_1.step_2
collaborator_1.step_1
end

it "fails when messages are received out of order between collaborators" do
collaborator_1 = double("Collaborator 1")
collaborator_2 = double("Collaborator 2")

expect(collaborator_1).to receive(:step_1).ordered
expect(collaborator_2).to receive(:step_2).ordered

collaborator_2.step_2
collaborator_1.step_1
end
end

What order are method arguments evaluated in Ruby?

The ISO Ruby Language Specification says that arguments are bound to parameters in the order in which they appear in the program text. However, the spec is vague about whether that also means that they are evaluated in that order.

The RubySpec, AFAICS doesn't say anything at all about the evaluation order of method arguments.

So, the answer seems to be: there is no guaranteed evaluation order for method arguments. It may be different between different implementations, it may be different between different versions of the same implementation, it may be different between two runs of the same version of the same implementation, it may even be different between two calls to the same method. They may be evaluated in parallel.

You just don't know.

Is the order of the equality operator important in Ruby?

Yes, there is a difference.

my_pw == hashed_pw calls the == method on the my_pw string and passes hashed_pw as an argument. That means you are using the String#== method. From the docs of String#==:

string == object → true or false

Returns true if object has the same length and content; as self; false otherwise

Whereas hashed_pw == my_pw calls the == method on an instance of BCrypt::Password and passes my_pw as an argument. From the docs of BCrypt::Password#==:

#==(secret) ⇒ Object

Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.



Related Topics



Leave a reply



Submit