I'm using the clearance gem to add authentication to a rails app. I would like to use a different layout called 'session' with the sessions and passwords controllers. In order to do this I'll need to override the sessions and passwords controllers, but so far I can't get either of them to use my alternative layout.
I've added a sessions controller that inherits from clearance and my layout file is in the correct place.
class SessionsController < Clearance::SessionsController
layout 'session'
end
I've done the same as above with the passwords controller. Now I add a route that I hoped would override the one that the clearance gem uses:
resource :session, controller: 'sessions'
But this has no effect and the application layout is used. How can I use a different layout with these controllers?
Overriding the layouts is simpler than this: See: https://github.com/thoughtbot/clearance#overriding-layouts
Clearance::PasswordsController.layout 'my_passwords_layout'
Clearance::SessionsController.layout 'my_sessions_layout'
Clearance::UsersController.layout 'my_admin_layout'
Related
I have a mixin for authorization checking which is included in application route so that all other routes get access to the mixin without explicitly importing it. However, I want to exclude my login route from inheriting it. How can I achieve that? One workaround is to import the mixin in all routes individually but that's error prone and don't want to resort to it unless I am sure that there is no way out.
Thanks.
That is not possible! All routes are nested inside the application route.
Better to have another parent route for all authenticated routes (e.g. /main) and you can extend the mixin here.
Other routes like login, register, forgot password,.. etc will be out of that authenticated route.
Lets say we were modelling repositories in an app. We would want to be able to see all of our repo's at /repos/.
We can create a repo at /repos/create. In our model a repo has a owner (user), going down this route I would want my first form field in my create.hbs template to be selecting a user.
But it may also make sense to create a repo through viewing a user at /users/userId/repos, and then perhaps the route being /users/userId/repos/create. The difference here would be that the first field of my form would have the user pre populated.
I know that I can reuse the same controller by specifying this in my route:
controllerName: 'repos/create'
(what would the ember generate statement/ the place to put this route in my folder structure be, for this complex route?)
But how would I pass in the user to the repos/create controller?
The comment by #Artych provided the best way to do this currently, so to expand on this.
In the end I created a repo-create component that may or may not be passed a user object. The logic for handling what to pre-populate can then be set in the logic of the component itself.
After this is was simply a case of having a one line template at both /repos/create.hbs and /user/repos/create.hbs, with the component.
I then followed the approach of using my user as my model in the routes/user/repos/create.js route and passing it to the component in my template as
{{repo-create user=model}}
With this approach I avoided doing anything explicitly on controllers, and moving up to Ember 2.x will be alot less painful.
I have an Ember 1.10 application with api support for 2 models, Students and Parents, and basic CRUD setup for each model, as well as the ability to read and write messages to/from Students and Parents when visiting their respective /show pages.
I must create an Inbox in which the messages as well as all the other data on Students and Parents is available and must do so without the ability to change or add to the api (i.e. I can' create a Messages endpoint).
Basically, I need to keep the Student and Parent models and controllers as they are, but need to be able to access them from routes namespaced under the Inbox like so:
Students
-inbox
-index
-edit
-show
Parents
-inbox
Inbox
StudentInbox <-- should use StudentsRoute and StudentsController
-index
-show
-edit
ParentInbox
-index
-show
-edit
So that visiting /inbox/students/123 will be using the model defined in the StudentRoute and the actions and properties defined on the StudentController. The InboxStudentsShowRoute should similarly have access to the StudentsShowRoute and Controller.
Instead of copying and pasting the existing code from the Student and Parent routes and controllers, is there a way to proxy actions fired from templates under the Inbox namespace to the relevant models and controllers and maintain the ability to pass in params.
For example, passing in params like ?unread=true while on the InboxStudentsShow route would pass these to the StudentsShowRoute and Controller (and bubble appropriately to it's parent route and controller) or editing a Student from student/inbox/123/edit template would work just as it does on the student/123/edit template?
New to Ember and know there has to be a better way to reuse existing code and proxy actions from a namespace. Any advice would be greatly appreciated!
I'd go here with creating a Mixin which holds same code for Route and specify controllerName, templateName in InboxStudentsShowRoute. Then, you extend from this Mixin in both routes. Model, template, actions, properties will be the same.
For example, passing in params like ?unread=true while on the
InboxStudentsShow route would pass these to the StudentsShowRoute and
Controller (and bubble appropriately to it's parent route and
controller)
I'm not sure what do you mean here by pass these to the StudentsShowRoute and Controller, but CONTROLLER properties changed in one route should remain the same in another route, because controllers are singletons in Ember. I don't know what do you mean by passing query param to another route, because if you transition to other part of your app you change URL and you can't have 2 urls at the same time, so how could query params be passed to another route?
In Ember 1.10 query params are defined in Controllers so I guess behaviour will remain the same.
Example of InboxStudentsShowRoute(move code from StudentsShowRoute to StudentsShowMixin, define controller and template name):
import Ember from 'ember';
import StudentsShowMixin from '../mixins/students-show';
export default Ember.Route.extend(StudentsShowMixin, {
controllerName: 'students/show',
templateName: 'students/show'
});
I have two controllers and two view: homepage and joblist.
I have a career.html.erb file and index.html.erb in homepage view. In career.html.erb, I have created a simple HTML form with labels and textboxes.
Homepage controller is a simple one with only view files. joblist controller is scaffolded. I have created jobs as well.
Now I just want my carrer.html.erb file form in homepage view to access and show in label the 'jobtitle' filed value of joblist controller.
Ho can I do that?
It is bit tricky. Whenever user made a request to webpage from browser, rails server map that request to controller actions by using mapping defined in routes.rb file. Routing tells rails application this request is for what controller. Now rails engine instantiate that particular controller and call action method on that controller object. SO NO METHOD OR VARIABLE IS NOT AVAILABLE IN VIEW. You can only get variables from that particular action.
For more details ruby rails web request response lifecycle
Views are rendered by controllers. You set instance variables (variables started by # sign) in controller and use these variables in view. So you need to set variables in same controllers from where you render views.
I am a Rails newbie. I am working on a small Rails4 project trying to improve my skills.
I am loosely following M.Hartl's tutorial.
As per the tutorial a custom user authentication is built.
However I would like to use Devise for User authentication.
Do I still need to have a Users controller as in the tutorial?
In which cases should I use/not use a Users controller when already using Devise?
Concerning the tutorial, do I just skip the controller generating part or do I have to map the actions to Devise?
You only need a users controller if you want to manage users separately from the normal signup/update process. I have a users controller so that admins can manage (create, edit, update, delete) users independently of the normal devise signup/update process.
The conflict with devise is probably because you have devise_for :users … in your routes file to set up devise and also have resources :users for your UsersController. This means that devise and your UsersController will be trying to share some of the same /users routes. You need to separate them out by changing the path that one of them is mapped to. You could either add, for example, :path => 'u' to your devise_for statement so that devise routes are mapped to /u and won't conflict with your UsersController on /users. Alternatively you could leave the devise_for alone (therefore still using /users) and instead change your UsersController routing to, for example, resources :users_admin, :controller => 'users' which would move your UsersControllers routes to be mapped to /users_admin. Note that this would change the path helpers from, for example, users_path to users_admin_path.
UPDATE
Following your comment/edit, I've had a quick look at the tutorial and I think that devise basically gives you the equivalent functionality of the user-related functionality which is developed from section 5.4 to about sections 9.1 or 9.2. (plus some extra stuff, for example, email confirmation, password reset, account lockout etc.). However, that doesn't mean that it's a drop-in replacement for that functionality, if you want to try and merge Devise with that tutorial. There are some things that look like they would work (e.g. Devise also defines a current_user method), but the routes etc. would be different, and devise splits things up into more controllers (separate controllers for registration, sign in/out, password reset…). The admin-type functionality (like in sections 2.2, 9.3, 9.4 - create/edit/delete/list other users) is what I've added a separate UsersController for in my app. Devise doesn't define a UsersController, but does use the users routes if you do devise_for :users without a path as I mentioned above.
So, more specifically:
You would only need a UsersController if you want to enable admin-type functionality allowing viewing/editing/deleting all users.
If you wanted to use devise in the tutorial, it would probably need some work to massage things to fit, changing helper links on pages etc. Sorry I'm not more specific; I haven't done that tutorial.
You would be missing out on the extra understanding that comes from doing it all manually yourself, but devise is a popular engine, so it's good to know as well. If you have the time, you could do the tutorial entirely, and then again with devise! It would help you understand some of the kind of stuff devise is doing behind the scenes. P.S: It can be instructive to look at the devise source code, even if you don't understand it all immediately.