In Rails 4 application I need to reload routes (routes.rb) for every request before the application uses it. Where should I put MyApplication::Application.reload_routes!
I have tried to put it in config/applicaion.rb,config/environments.rb but it's not working.
I have also tried to put it in before_filter of ApplicationController and it's also failing.
RoR api is brief on how to use it.
So any assistance/guidance on this will be greatly appreciated
Seriuosly i would never do that. It is massive intervention into Rails internals. Just configure one dynamic route to a single controller. Then load some Command(Service)
according to the dynamic part of the url from the db, deserialize, instantiate and pass
the current controller as a reference to this dynamic service constructor.
The dynamic service you are loading should be implemented according to the following refactoring technique:
Replace Method with Method Object
Another Option would be to load a lambda/Proc because it would automatically have the controller scope once instantiated
Related
Creating in-repo-addon in Ember.JS gives a lot of possibilities. Today I've stumbled into a case when I wanted to register all classes in directory (for example my-dir) into Dependency Injector (same way it's done with services by Ember, but I wanted to use some other namespace).
For example I want to allow developer to create multiple classes inside proxy directory, and register all of them in DI under proxy: namespace. So later we can use:
Ember.Component.extend({
myProxy: Ember.inject('proxy:my'),
});
You'll need to do this using an initializer. More details on this here: https://guides.emberjs.com/v2.12.0/applications/dependency-injection/
The hard part may be getting all proxy items in s folder to automatically register ...
Edit
Looks like I didn't spend enough time thinking about this. You should be able to do at least part of this easily. There are two parts to this.
Part 1
Ember currently uses the ember-resolver to handle lookups for various items. If you check the tests for the resolver you'll notice that you should be able to map in anything you want: https://github.com/ember-cli/ember-resolver/blob/master/tests/unit/resolvers/classic/basic-test.js
So in your case, if you do a Ember.getOwner(this).lookup('proxy:main') from within an Ember instantiated class (a route, controller or component for instance) it would look in app/proxy/main.js which your addon could be populating.
Details on the Ember.getOwner lookup are available here: https://emberjs.com/api/classes/Ember.html#method_getOwner
Part 2
So at this point you can lookup proxies (which would be doable in an init method). But if we want to get truly elegant we'd want to allow Ember.inject.proxy('main') syntax.
Doing so would involve calling a private method inside of Ember.inject in an initializer. Because that naming scheme is changing in the new Javascript modules RFC, it may be unwise to try to add this syntactic sugar ...
So I'd advise avoiding touching that private API unless it's really important to your app design.
I have created a mock application to illustrate the situation I am facing: Mock App
In this application; I have created a service with a single boolean property and a function to toggle that property (x); and two components (one to toggle the service's property; the other to observe the number of toggles and display it). The observer lies in toggle-observer. It is added directly to service's property as: myService.x. The code is not working as is; however if the comment at line 14 of toggle-observer.js is commented out; the observer starts working.
My question is that, do I need to perform a get to the whole path of a nested observer property to get it working? Is this the expected behavior? If so, can somebody explain why? My best regards.
Note: This is a mock example to illustrate the case; it is not related to anything I am designing in a real app. I am trying to avoid observers as much as possible; but I ran into this situation while trying out sth. and decided to ask it.
From ember guide service
Injected properties are lazy loaded; meaning the service will not be
instantiated until the property is explicitly called. Therefore you
need to access services in your component using the get function
otherwise you might get an undefined.
From ember guide, unconsumed computed properties do not trigger observers.
By combining the above two concepts, we can come to the below conclusion,
You haven't used myService any of the property inside toggle-observer component so it will be undefined until you explicitly call get function or use it in template.
Unless you use it x property in toggle-observer component, then it will not trigger observer. You need to consume it either in toggle-observer.hbs file or in init method.
Previously when I developed ember application I used App as my global object and every class was stored in this big object.
Like this
window.App.MyModel = Em.Object.extend({});
And in the browser console, I was able to do
App.MyModel.create();
So it was really easy for me to access MyModel class.
Now I started experiments with Ember-CLI, I don't have much experience with this kind of tools. I followed the documentations and I created my model Service like this.
var Service = Ember.Object.extend({});
export default Service
But now, how to access Service class from browser console?
Only way I found was:
App.__container__.resolve('model:service')
But I don't like it much. Is there better way? Btw, can you please explain how export works? Or is there some source (documentation, article) where I can study it?
Thanks a lot for response.
If you're aiming to have something available in most places throughout your application you'll typically want to register it on the container.
There are multiple ways to access the container, and you're correct in that the one you found was less than ideal. The running joke is "any time you directly access __container__ we need to add more underscores."
To directly control how things are registered on the container and injected into the container you typically want to use an initializer. Using initializers in ember-cli is super-easy, they're executed for you automatically.
Checking out the documentation you can see that you get access to the application's container as an argument which allows you to manipulate it in a safe manner.
Once you have access to the container you can use register and inject to make content easily available in particular locations. This was introduced here. One note, accessing things inside of the container from outside the context of your app (browser console) will require the usage of App.__container__ and that is the expected use pattern.
And the export you're running into is an ES6 module system construct, it's not Ember-specific. Playing with the ES6 module transpiler can give you a good sense of what goes in and what comes out in "we can do this today" type of JavaScript.
For ember 3.22, application classes can be accessed like so:
Ember.Namespace.NAMESPACES[1]._applicationInstances.values().next().value.lookup('service:state-events')
Note, you may need to modify the index in NAMESPACES[1] to be something other than 1. You can determine which namespace is your application when this returns true:
Ember.Namespace.NAMESPACES[1] instanceof Application
This approach is how ember-inspector accesses ember applications: https://github.com/emberjs/ember-inspector/blob/50db91b7bd26b12098cae774a307208fe0a47d75/ember_debug/main.js#L163-L168
In the notes of this commit, the Ember team have made it very clear that App.__container__.lookup() is not the way to get at controllers. Instead we should use the needs property.
I understand the rationale behind this, and the idiomatic way to access singleton controllers.
However, in my app, I have some cases where I need instance controllers. In that case, I am using App.__container__.lookupFactory() to get at the prototype which I can then create() or extend()
Is there a better way to do this (without using __container__?
Edit:
Here is an example use case.
App.MyContainerView = Ember.ContainerView.extend
...
addChildView: ->
#get("content").pushObject(App.MyChildView.create(...))
The above example will push a new view onto the stack (allowing views to be dynamically created)
However, these views will (may?) not have the right container (and other properties?) set due to being created using App.MyChildView.create(). This is especially true in cases where we are doing a partial integration of Ember into an existing app.
The way to create these views would instead be:
App.__container__.lookupFactory("view:my_child").create()
In which case everything would be ok.
Additional use cases exist, for creating instance controllers outside the context of the router.. but the idea is the same.
I don't know if you're still looking for an answer. I am also struggling with how to do things "the Ember way".
This answer put me on the right track, and should be relevant to your question:
"Please ensure this controller was instantiated with a container"
As for me, I had the same problem as in the above question: when I manually instantiated my App.AnyOtherController with App.AnyOtherController.create(...), then inside this controller, I could not access dependency injections (such as a session object that I make available to all my controllers and routes).
Instantiating the same controller this way solves the problem by giving the controller a container:
this.container.lookupFactory('controller:any_other').create(...)
You should be able to access this.container from any view, and I guess, any controller, as long as they have been given a container.
You can Ember.String.decamelize('AnyOther') to convert the CamelCase controller name to a suitable string.
More on containers here: http://ember.zone/beginning-to-understand-the-ember-js-container/
If it doesn't help you, I still hope this helps someone out there, as this container stuff is a bit tricky at first...
how can I use the controllers created at
/administrator/components/com_mycom/controllers/*
in
/components/com_mycom/mycom.php
In detail:
I have a »log« controller with an »add« method, and I would like to use this from the frontend. I one is not logged in in the backend the task is not executed and a 500 error rises. So just would like to include the backend controllerpath in the frontend, so that JController::getInstance( 'Mycom' ) still works.
Greetings…
EDIT:
After a long time of searching I could find a more or less undocumented Parameter of the:
JController::getInstance() method, namely the second one: $config = array(). Going through the source code I found out that there is one key of the »config-array« that is of interest, which is: »base_path«.
The call of:
JController:getInstance( 'Mycom, array('base_path' =>JPATH_ADMINISTRATOR.DS.'components'.DS.'com_mycom')' );
always delivers the backend controller and one can use them safely in the frontend, BUT one must take care that then also the views are taken from the backend side of the component. In my case, I just use it to make ajax-calls so it does not matter, but one needs to be careful with using this method when planning to create »frontend views« with »backend controller«.
Greetings…
I had recently a similar problem where I wanted to use the whole CRUD system form back-end also in front-end.
This is the method that worked for me (and I am not saying that this is recommended or best practice):
I've just modeled the folders / file structure from backend. PHP files contained something like:
require_once JPATH_ADMINISTRATOR . '/components/com_mycom/controllers/log.php';