How to resolve Rails model namespace collision

风流意气都作罢 提交于 2019-12-29 04:22:23

问题


The story so far:

I have a rails app with a model named "Term". All is well until trying to install Cucumber. Upon running

rake cucumber

I get

Term is not a class (TypeError)

This happens because Cucumber includes another gem, 'term-ansicolor' (to do the nifty colored text output in the console), and term-ansicolor defines a module named "Term". Cucumber includes term-ansicolor before including the Rails models, thus "Term" is already defined as a module when loading the "Term" model. Top-level modules and classes cannot have the same names in Ruby, thus the collision.

Preferring not to rename the model, I set about patching the term-ansicolor gem. This proved harder than I thought. I changed the Term module name to "ANSITerm", but I can't figure out how to get Cucumber to load my modified gem, which I've put into RAILS_ROOT/vendor/gems/term-ansicolor.

Any ideas? Am I barking up the wrong tree?


回答1:


Two solutions:

1) Change your app's Term model to be something else.

2) Patch term-ansicolor to have a namespaced Term and use that gem instead.




回答2:


Here's what I did:

sudo gem uninstall term-ansicolor
sudo gem uninstall cucumber

Download sources for term-ansicolor and cucumber from github
Search term-ansicolor source for "module Term" and replace with "module ANSITerm"
Search cucumber source for "include Term" and replace with "include ANSITerm"
Search cucumber source for "::Term" and replace with "::ANSITerm"

sudo gem install term-ansicolor from my local repository
sudo gem install cucumber from my local repository

Now I have two gems to maintain, but that seems easier than changing all the model references in my app.

Comments/suggestions welcome.




回答3:


I did get a namespace collision with my application model Node and Capybara::Node in my specs. It was sufficient for me to explicitly state toplevel namespace in specs to fix the problem:

it "should find the specified node scoped under the current user" do
  ::Node.should have_received(:find_by_id_for_user).with(node.id, user)
end


来源:https://stackoverflow.com/questions/1736747/how-to-resolve-rails-model-namespace-collision

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!