I recently authored a gem called 'setting' (found here). The extends ActiveRecord with a module named 'Setting'. I understand that gems are supposed to use the namespace they are named, however when testing this caused collisions with ActiveRecord models with the same name (a Setting model). Does a standard exist for creating a private module namespace? I don't need users of the gem to ever access the module outside the extension in ActiveRecord. Do I have any options outside of picking a less common name?
Since you're writing an Active Record extension, you could place your module inside the ActiveRecord namespace:
module ActiveRecord
module Setting
end
end
Other than that, no, there's no practical namespace solution for gems with very common names.
Related
If a Rails app has two engines that define the same method, which version "wins"? How is it decided which one gets executed when the method's name is evoked?
For example, both the Rails engine blacklight and another Rails engine meant to modify Blacklight's functionality define a method like this:
module Blacklight
class SuggestSearch
def suggestions
...
end
end
end
The method definition is the same in the two engines but with ... in place of different content. The second of the engines is meant to override the functionality of the first.
The two engines are used in the same app, like this:
gem 'blacklight'
gem 'trln_argon'
How does rails know which engine modifies the other? How is the second engine's definition of suggestions made to prevail?
After upgrading my Rails app, I have run into a problem where the name of one of my models are conflicting with another class in Rails, namely Configuration.
Is there a way for me to (from a controller) explicit use my model class Configuration instead of ActiveSupport::Configurable::Configuration? What is the default namespace for my models?
You can use ::Configuration to call your class. It means that you're referring to the constant Configuration from the toplevel namespace. But I think it's annoying. You can rename your class to avoid this.
I'm brand new to rails (and ruby) and having a a lot of trouble with accessing different namespaces. Specifically, I can't access the namespace of the flickraw gem from within a controller class:
class ImageSourcesController < ApplicationController
def show
list = flickr.photos.getRecent
...
end
end
Calling this method, I get the response:
undefined local variable or method `flickr' for #<ImageSourcesController:0x00000005006658>
I am using bundler, which I thought ensured that the methods of all gems in the gemfile are required by rails.
EDIT: I'm stupid, turns out I just needed to reset the server!
It is a good idea to create an initializer for flickraw:
# config/initializers/flickraw.rb
FlickRaw.api_key= ENV['FLICKR_API_KEY']
FlickRaw.shared_secret= ENV['FLICKR_API_SECRET']
If you are creating a open source app you may want to use ENV variables to store your API key and shared secret. The dotenv gem is a really nice tool for that.
You also seem to be confused about namespaces in Ruby. Ruby doesn't actually have namespaces in the same way as for example PHP which has a special keyword and namespace accessors.
Ruby has modules which act as both namespaces (grouping classes, constants etc.) and traits. Foo::Bar.create() is an example of accessing a class method on a "namespaced" class.
module Foo
class Bar
def create
end
end
end
Your flickraw example is simply accessing nested properties (which does'nt really have anything to do with namespaces):
flickr.photos.getRecent
Your taking the object flickr (which flickraw creates when we require flickraw) and sending it the message photos which returns a FlickRaw::Flickr::Photos instance.
We then send the message getRecent to flickr.photos
In my Rails 2.3 app, I found that the problem emanates from namespace collisions between an existing ActiveRecord model and a gem I recently added.
Specifically, I was trying to add jammit support to the app. One of jammit's dependant gems require's 'platform', which introduces a Platform module into the app's namespace. However, I already have an AR class with that name, and renaming it will introduce a lot of additional work and possible bugs.
I was wondering if there's a relatively simple way (using ruby's metamagic or whatnot) to prevent this namespace collision without having to rename my class or alter the actual gem. Thanks.
EDIT:
Instead of renaming/wrapping the class Platform throughout my app, and since the module Platform is only required by one other gem, I resulted to forking both gems, renaming Platform to XPlatform (both for the original gem and the one that imports it), and rebuilding them both. That seemed to work [sigh].
if the conditions are unavoidable when you cannot change the name
try wrapping your activerecord class in a module
module YourModule
class Platform < Activerecord::Base
named_scope :your_scope, lambda {#your code here}
end
end
So the only change that you have to do is something like
YourModule::Platform.your_scope
At the top of the class before any actions, you could just make an alias.
NewPlatform = ActiveRecord::
And just use the alias in the action for that class to avoid namespace conflicts.
I want to create a model called 'File', but it is a reserved model name is rails. I can't think of anything else sane to call the model, so I was wondering if there is a standard way of dealing with this issue, for example adding a prefix or suffix (_File, FileItem, etc)?
This problem is addressed with modules:
Modules are a way of grouping together methods, classes, and
constants. Modules give you two major benefits:
Modules provide a namespace and prevent name clashes.
Modules implement the mixin facility.
[...]
Modules define a namespace, a sandbox in which your methods and
constants can play without having to worry about being stepped on by
other methods and constants.
In your case:
module MyRailsApp
class File
...
end
end
whereby your File class is used as MyRailsApp::File. This is the typical solution in Ruby, in Ruby on Rails this might be handled differently, please see the following references for an in depth discussion:
Handling namespace models (classes) in namespace
ActiveRecord: Can haz namespaces?
Namespaced models and controllers
Namespaced models
A simple alternative to namespaced models