Rails: is there an Engine.root? - ruby-on-rails-3

Rails.root returns a Path object specifying the root of a Rails project.
Is there an equivilent for Rails engines? Like Engine.root? If not, how else could I build up a path from the root of my Rails engine?

Lets say your engine file is set up like this:
module MyEngine
class Engine < Rails::Engine
#......
end
end
You can call root on the Engine class like this:
MyEngine::Engine.root

John's answer is right, but I'd clean that up a little bit like this:
When you mount your engine within your routes file add an alias first.
mount YourEngineNameHere::Engine => '/optional_namespace', as: 'your_engine_name'
Then do your_engine_name.root_url

Related

Rails 3 optional scope url generation

I have the following defined in my routes.rb
scope '(:subdomain)' do
resource :highscore
end
now I can reach the same resource on these paths
/highscore
/test/highscore
however, when I generate a url using
highscore_path
it will always generate the /highscore path, however, i'd like it to generate a /test/highscore path when inside the test subdomain
i tried manipulating default_url_options or
highscore_path(:subdomain => 'test')
but it always omits the test. How do I work around this, preferrably without having to change all of my urls?
Turns out the specifier 'subdomain' was silly :( replace that with anything else and it'll work!
I've overwritten default_url_options in the application_controller with
def default_url_options
return {:identifier => 'test'}.merge(super)
end

Monkeypatching for a local method in Rails 3

I have a situation like below:
Module Task
def get(a)
fetch(a)
end
def fetch(a)
query(a)
end
def query(a)
puts a
end
end
and only get method is called from outside of module like
Task.get('name')
I want to monkey patch only method query to make some change in response of get method since it calls query intern.
Please suggest a way to do this.
In order to monkey patch in cases like these, we need to include a file in lib folder. In this case you need to make a file inside lib folder of the same name. In that first include the module TASK and then use MODULENAME.module_eval and add the methods in this. In this file u can override the methods in the actual module and add methods to it too.
In order for this to work you will have to require the file u created in lib in config/initializers/app.rb
Incase the module you are over riding is present inside a folder (like in case of a ruby gem) you need to include the whole path. For ex.
Module_1.Module_2.module_eval
where module 2 is inside module 1.

Heroku/Rails route example.com to mydomain.example/example

My rails app is a way for users to create their own basic website. So each of them will have a root folder that is example.com/user/1. They will have other pages like example.com/user/1/about etc. How do I configure Rails and Heroku so that something like www.user1.example points to example.com/user/1, and something like www.user1.example/about directs to example.com/user/1/about?
The way I did in my app was first have the list of user domains in the database. Then create an advanced constraint
http://edgeguides.rubyonrails.org/routing.html#advanced-constraints
In this case, my constraint class looks like this:
class UserDomainConstraint
def self.matches?(request)
UserDomain.all.map(&:domain_name).include? request.domain
end
end
And then use that constraint in the route
root to: 'user_domains#index', :constraints: UserDomainConstraint
My action then takes a look at request.domain and acts accordingly.

tradeoff routes and views rails 3

here it's routes.db
resources :licenses do
resources :sublicenses do
resources :time_licenses
end
end
Then there is a client application that calls time_licenses_controller for creating new time_licenses, the controller responds with a json file, but i don't need to show any view.
Somewhere else instead i need to show to the client an index file including all time_licenses for every sublicense.
That's the path
license/:id/sublilicense/:id/time_lincenses
Now i have a problem with the routes. When i call the create on time_licenses_controller i get this error:
No route matches "/time_licenses.js"
that i can solve changing the routes.db file like this
resources :time_licenses
resources :licenses do
resources :sublicenses
end
but in that case i get the same error linking the index view.
What do you suggest me? Do i have to create two different controllers?
Since you are using nested resources, you will always need to specify license and sublicense while specifying the path to timelicense.
Your path helpers will be:
license_sublicense_timelicense_path(#license, #sublicense, #timelicense) and so on
You can get the path names for the timelicense by
rake routes
Refer rails guides - nested resources for any doubts.

Rails 3 with Liquid Custom Tags not found

I am trying to create a set of custom tags for some liquid templates using Rails 3. I added a 'liquid_tags.rb' in my lib/ directory with content like this:
class UserControls < Liquid::Tag
def initialize(tag_name)
super
end
def render(context)
tag = "<b>TAG</b>"
end
end
Liquid::Template.register_tag('user_controls', UserControls)
When I try to get the tag in my view via '{% user_controls %}' it tells me the tag isn't found.
Any ideas?
Thanks in advance.
That's right, as marcusmateus says, Rails won't load anything in the lib directory automatically even if you have added it to the autoload_paths unless the class or module name inside the file matches the file name.
To sort this problem just put the custom formatters inside the lib directory, each in their own file (I tried using a module to wrap them all up but no luck)
class MyCustomTag < Liquid::Tag
def initialize(tag_name, params, tokens)
# do something
end
def render(context)
# do something
end
end
Then created an initializer (in config/initializers) responsible for registering the custom tags with Liquid. i.e.
Liquid::Template.register_tag('custom_tag', MyCustomTag)
Liquid::Template.register_tag('custom_tag', MyCustomTag2EtcEtc)
Are you sure that file is getting loaded? If it's not, then register_tag is never getting called. I would throw in a puts statement above register_tag to debug it, make sure that the file is actually being loaded. You may to move the register_tag into an initializer
on config/application.rb try adding this line
config.autoload_paths << File.join(config.root, "lib")
I believe files are only autoloaded if the name of the file matches the name of the class it contains. In the question you state that your file is named 'liquid_tags.rb', but your class is named UserControls... if you rename your filed 'user_controls.rb' it should begin autoloading.
I think it's not loading problem -- I have it also. The tag is being loaded, you can print the current registered tags:
Liquid::Template.tags.inspect