Introduce a context for rendering fixtures ERB.#13022
Conversation
|
Could this break applications that rely on the fact that currently methods are leaked? |
|
It depends on how you define "break". This only impacts fixture code, so it won't break the folks who don't have tests at all. Assuming you have tests, and you run them when you upgrade Rails, this will turn flaky tests into definite failures. I think the fixtures load order is currently decided by this call to For some restricted definition of "break", this is a breaking change. I am willing to write the documentation needed for devs who run into this to understand what's happening. At the same time, I consider that the change turns ticking bombs into problems that are immediately visible. For context, imagine this exploding all of a sudden in a continuous integration / continuous deployment environment. 💣 😢 |
|
of course by breaking I meant the tests and not production code. I don't see a reasonable way to issue depreciation warnings only in these cases so we need to compensate with docs. /cc @rafaelfranca |
|
@senny I figured you already knew the answer, and were asking for documentation purposes, or to have the answer spelled out in the PR log. Sorry, I misunderstood and my answer was weird :/ I didn't see a |
|
@pwnall sorry for being vague. It's good to reflect these thoughts in the PR so we can later link to it. I'll prepare the release notes and the upgrading guide today. I'll let you know when things are ready. |
|
@senny I added a Changelog entry and a paragraph in the fixtures documentation. Can I do anything else to help document this? |
|
You can add a section to the upgrading ruby on rails guide I pushed a first draft of the 4.1 release notes. You can add an entry in the notable changes section and even link to the upgrading guide. |
activerecord/CHANGELOG.md
Outdated
|
@senny Thank you! I added notes in the upgrade guide and 4.1 release notes. I look forward to your feedback! |
activerecord/CHANGELOG.md
Outdated
There was a problem hiding this comment.
Let's use the short version from the release notes here as well. If people want to find out more then RenderContext and the upgrade guide is the place to look:
- The ERB in fixture files is no longer evaluated in the context of the main object. Helper methods used by multiple fixtures should be defined on the
ActiveRecord::FixtureSet::RenderContextclass.
|
I added some minor comments. This is looking good. |
There was a problem hiding this comment.
This construction is very confusing. It only work because users will reopen a framework class to inject behavior. Could not we simplify this and make users create their own context and configure the fixture to use it? Or even better we can expose the context class and let people inject their own modules there. Something like:
Fixtures.context.include MyHelpersThere was a problem hiding this comment.
@rafaelfranca You can currently do
ActiveRecord::FixtureSet::RenderContext.include MyHelpersI think we can get to where you want by
class ActiveRecord::FixtureSet
def self.context
ActiveRecord::FixtureSet::RenderContext
end
endIf I read this right, Fixtures is deprecated, so what you wrote would work and output a deprecation warning. The line below is slightly longer, but would work as is.
FixtureSet.context.include MyHelpersWhat do you think?
|
I discussed this change with @rafaelfranca. We came to the conclusion that we should:
class Fixture
def self.context
@context ||= Class.new do
def get_binding
binding()
end
end
end
end
|
|
👍 |
|
This doesn't quite work :( I tried adding this to class ActiveRecord::FixtureSet
def self.context
@context ||= Class.new do
def get_binding
binding()
end
end
end
endOne problem is that The other problem is that unless I define Thoughts? |
|
We can define |
|
About the |
|
@rafaelfranca In the end, we'll have a namespace where we have to pay a lot of attention when we add new names. I think that @senny I think that is correct. I also think it has to be defined in a "clean" namespace, because that namespace will be in lookup scope. |
|
I'm fine with a clean namespace but I don't want to see that module hack. It is ugly and hard to understand. So if there is a way to make a clean namespace without it 👍 |
|
@rafaelfranca What do you think about this version?
|
|
Very good ❤️ |
|
@rafaelfranca The other alternative I have is along the lines of ActiveRecord::FixtureSet::File.define_singleton_method(:render_context) do
Class.new ActiveRecord::FixtureSet.context do
def get_binding
binding()
end
end
end |
There was a problem hiding this comment.
We will have to use send here since include is not public on Ruby 2.0
There was a problem hiding this comment.
Good point! Thank you!
|
@rafaelfranca Thank you! I'll go through the docs and update everything. |
I ran into this issue while trying to use binary data in my fixtures. The following guides motivated me to write this patch.
http://realityforge.org/code/rails/2006/04/06/loading-binary-data-into-rails-fixtures.html
http://www.tamingthemindmonkey.com/2011/08/18/rails-binary-data-in-fixtures
These define a new method right in the fixture file. I'm sure other people do this every once in a while too. With the current code, method definitions leak to other fixtures via the main object. This introduces subtle test inder-dependencies. Methods won't leak after this patch. (proven by new test case)
http://stackoverflow.com/questions/12644057/how-to-use-binary-data-in-rails-fixtures
This is a nice approach that's amenable to being packaged into a gem, except there is no clean place for adding this sort of functionality.
I look forward to your feedback.