Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use define_method when method name contains weird characters. #9274

Merged
merged 1 commit into from Mar 27, 2013

Conversation

KrzysiekJ
Copy link
Contributor

In delegate_to_scoped_klass method in ActiveRecord, plain def was used when defining methods with weird characters in names, which resulted in syntax errors. I've changed it to use define_method instead and added a regression test for scope names with spaces.

This could be also rewritten to use a block instead of a string in module_eval, but in pull request #9206 I've read that it may impose some performance penalty, so I didn't change it as I don't know how important it is.

@sikachu
Copy link
Member

sikachu commented Feb 13, 2013

I can see how that would break, but ... would you tell me why are you having a scope method which contains space? I don't think this is a general use case here as people would normally do method_with_underscore.

@lexmag
Copy link
Contributor

lexmag commented Feb 13, 2013

👎

@rafaelfranca
Copy link
Member

I don't think this is something we should support

@mhuggins
Copy link

Definite 👎. Why do this?

scope :"title containing space", -> { where("title LIKE '% %'") }

When you could just do this?

scope :title_containing_underscores, -> { where("title LIKE '% %'") }

All the example documentation regarding scope uses symbols with underscores for scope names.

@sikachu
Copy link
Member

sikachu commented Feb 13, 2013

FTR: I'm actually -1 on this one, but want to see the use case first.

@KrzysiekJ
Copy link
Contributor Author

Imagine the following model:

class Ticket < ActiveRecord::Base
  @priorities = ["not important", "minor", "major", "very important"]

  class << self
    def valid_priority? priority
      @priorities.include? priority
    end
  end
end

Then I may want to ease filtering by those priorites, so I write the following code:

class Ticket
  @priorities.each do |priority|
    scope priority, where(:priority => priority)
  end
end

This allows me to do things like

@tickets = @tickets.send params[:priority] if Ticket.valid_priority? params[:priority]

without caring about string processing of priority names in the views and controllers. It may occur that those scope names won't be hand-typed anywhere in the code, but if there is such need, it still can be done with send or by employing method_missing to convert dashes to spaces.

The above probably isn't a very important and convincing use case, but this functionality is already present in the code — delegate_to_scoped_klass checks if method name looks like /\A[a-zA-Z_]\w*[!?]?\z/ and if not, it executes different code in module_eval, which calls the method with send. It's just the def which is written improperly. So my patch isn't essentially adding any new feature, it's just fixing the broken code. If you don't want to support non-standard scope names, then probably this part of code should be removed.

Topic.send :"title containing space"
Topic.approved.send :"title containing space"
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imagine you didn't know about this pull request or issue, and you're reading this test. What does it communicate to you?

@jeremy
Copy link
Member

jeremy commented Feb 14, 2013

@KrzysiekJ Agree this should work just on the basis of consistency. I wouldn't keep pushing it as a feature, though. If anything, we want to encourage using "Ruby method" naming for scopes. I made a couple comments on the patch. Thanks! 😁

@KrzysiekJ
Copy link
Contributor Author

Thanks for the review. I've removed module_eval usage, added a comment to the test and amended those changes to the first commit.

@senny
Copy link
Member

senny commented Mar 18, 2013

can you rebase your branch and add a CHANGELOG entry?

@KrzysiekJ
Copy link
Contributor Author

Ok, I've added the entry and rebased branch.

@senny
Copy link
Member

senny commented Mar 18, 2013

@KrzysiekJ great! let's wait for @jeremy to merge it.

@volochaev
Copy link

👎

@jeremy
Copy link
Member

jeremy commented Mar 18, 2013

@KrzysiekJ No need for a changelog entry. Sorry about that! Prefer to treat this as a cleanup & refactoring, not to advertise it as a new feature.

The comment on the unit test is good, but the test code itself doesn't communicate what's going on. Rather than defining the scope elsewhere then calling it in the test, consider defining the scope within the test. Also, asserting that no exceptions are raised is imprecise: "nothing blows up!" Assert that the scoping returns what you expect it to.

@KrzysiekJ
Copy link
Contributor Author

@jeremy No problem, I’ve removed the changelog entry, improved the test and updated the pull request.

rafaelfranca added a commit that referenced this pull request Mar 27, 2013
Use define_method when method name contains weird characters.
@rafaelfranca rafaelfranca merged commit 72de894 into rails:master Mar 27, 2013
@KrzysiekJ KrzysiekJ deleted the spaces_in_scope_names branch March 27, 2013 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants