Devise in mogoid for multi-users with different data - ruby-on-rails-3

I am using rails 3.2.7, mongoid 3, and i am trying to use devise for users accounts.
Before i'll start: i was searching a lot for my problem, and i read many tutorials, byt none fit to my need.
I have similar problem like devise and multiple “user” models
but i am using mongodb so i think the problem is not exacly the same.
I have 3 types of users":
Manger which can have many places and can manage them(edit info).
User which can search for places(even no user can) and create their places lists. Also user can comment and note the places.
Administrator who can edit/delete anythig, so admin is a god.
So, all of them have different data(except of login info) and i don't know what solution is the best.
STI would be good if they would have the same data, and different actions, but data are different too(but i am using mongoid, so maybe it would be fine?)
Single user model with roles is another solution but i don't know how to store different data, maybe with polymorphic? I don't fully understand how it should be implemented with devise and maybe cancan.
Maybe there is third?
I know what is STI, polymorphic associations, also how to implement roles with CanCan, but the problem is that i dont't know how to connect them with devise?
If there would be few sign in forms or one, it doesn't matter. I don't have to use devise either.
I found few tutorials/examples how to use devise, monogid, roles for multi-users applications, but they are when users store the same data, so they don't fit for me.
Can you give me advice, or a maybe a link which could help me?
Thanks for help :)

I would recommend building different controllers for different use cases. Don't build dependencies of different views inside the data. This way you are free to use the data for other use cases or other user groups without changing it directly.
Simply create controllers for the different use cases. This way you can change them any time without changing your data model.

Related

Rails 3 - Model related to current user in controller

We assume an authentication system is setup and we have access to a variable current_user, e.g.: using the Devise gem.
We have two models, User and Thing, User has one Thing.
In the controller, what's the best practise in order to get the right Thing to create/delete if we assume that a User can only create/delete his own Thing.
Eg for create action.
OPTION 1 (standard) :
#thing = Thing.new(params[:thing])
#thing.save
And we set the user_id in the view.
OPTION 2 :
#thing = current_user.create_thing
And we don't bother about setting the user_id in the view.
Both works but I would like to know if one must be avoid or is better and why.
Thanks!
I personally think the second option is better because (as you say) you don't have to mess around with a user_id (neither in the view nor specifically within the controller).
The first option is only useful if you want to allow users to set things for other users than themselves. If you don't want to allow this, the first option even introduces a possible vulnerability. Malicious users can try exploiting the user_id field in the view. So, assuming users can only set their own things: definitely option 2.
If you are using devise gem, Its better to play with current_user. This will be more secured than passing users id.

Rails 3 + Devise with different model name

I'm sharing one database for two web applications. The User model is already being used for one of these apps, so, in order to sign in to the other one, I had to create another model to avoid mixing users info.
I could make Devise work for this new model, called SystemUser. The problem is now I'll have to use every variable with another name. For example: current_system_user, system_user_signed_in?, etc. I'm using these variables, with their original name, across the whole application, and I would like to know if there's a way to avoid overwriting it. For example: by creating a method called current_user that returns current_system_user, and that way with the other variables mentioned before.
I think this should do the trick:
devise_for :users, class_name: 'SystemUser'
have you considered using CanCan for roles?
https://github.com/ryanb/cancan
I could finally solve the issue by generating the Devise views again. I don't know why, but the devise/sessions folder was missing, and it was doing it with another view, and when I started using it, it worked.
Thanks anyway.

Kohana 3 auth username as number

I want to use numbers as username in Kohana Auth. For example, username 100001?
While adding new user Kohana returns me error: ORM_Validation_Exception [ 0 ]: Failed to validate array
Is is possible to user numbers as username in Kohana?
EDIT: This answer looks simpler and better than mine, but try to understand it at all.
You need to extend User Model, I'll help you using auth with the ORM driver.
Steps to extend User Model:
If you didn't yet, configure Auth module to use orm and create a database table with the fields you want. Here is a good example of how to doing it (It's an old tutorial using ko3.1 but you can still learn from it). PS.: you can have any columns at the 'users' table and you don't need to have the 'username' column if you do not want.
Open and read carefully this file: MODULES/orm/classes/model/auth/user.php (It's self documented and I hope you understand it. If not, stop reading this answer here and read the kohana docs. Some shortcuts: Auth - Kohana User Guide, Auth (orm) methods, addons:auth
Copy the file (don't edit the original) to APPPATH/classes/model/auth/user.php and edit it how you want. Some functions that you may like to edit are: rules, filters and unique_key (<- useful). Be creative, you also can add custom functions.
Test and change whatever else needed.
You can change the login method to works as you like. You can set login by e-mail, make a custom validation method or parse values before saving in the database (see public function filters()). This is helpful for whatever you try to do with auth module using ORM... But... if you really don't want to use ORM, you can build your own driver, learn how.
I made this some time ago in kohana 3.2 but I think you won't get problems with 3.3. If you still have questions, this question on kohana forum may help.

Rails 3 CMS + blog wanted to fit existing site. Unobtrusive and Lightweight

I'd like to add a CMS and blog to a web app. One that won't get in the way. There's not a lot of content, but enough that we want non-devs to be able to revise pages and probably add and remove them too.
We have a substantial app that can't be touched by the CMS, not a site that we're migrating.
How have you dealt with this situation?
Would you advise:
Running two apps (a content app and the 'app' app)
Plugging in a light weight CMS
Rolling our own using gems/plugins for WYSIWYG
Details
We'll be adding a bug ticketing and support system later too. Probably built into the app.
We'd like the users of the app to be able to comment on pages and blog posts, file tickets, etc. all from their main account, so it seems to make sense to build it into our app, rather than as an extra app. Love to hear war stories on this.
Should be:
Unobtrusive (Shouldn't interfere with the existing app)
Must not mess with Devise, DeclarativeAuthorization, or Omniauth. We've got extensive user accounts, permissions, authentication mechanisms and groups setup. These must stay.
Lightweight (prefer something dev friendly than feature loaded)
Desired Features:
Basic WYSIWYG for content editors
Lets us handle accounts (with Devise)
and maybe even permissions (with DeclarativeAuthorization)
I've read this similar question, but the author seems willing to have something a bit more intrusive.
Simple Rails 3 CMS Gem/Plugin?
Options Found
Refinery seems to have a lot of features, but at a cursory look it needs a lot of control over what's going on: http://refinerycms.com/guides/attaching-refinery-cms-to-an-existing-rails-application It says it's modular, but it seems like there's a big chunk of non optional stuff in there.
Radiant seems a bit monolithic as well
http://groups.google.com/group/radiantcms/browse_thread/thread/b691cf9ab644a8b2
ComfortableMexicanSofa seems a bit closer to what I want: https://github.com/twg/comfortable-mexican-sofa
Adva-Cms has the right philosophy but appears to be dead. Adva-Cms2 isn't ready
http://adva-cms.org/
Governor seems good, but maybe a bit too young and lean
https://github.com/carpeliam/governor
Conclusion
So far rolling our own, or using ComfortableMexicanSofa seems like the bet, but I'd like your thoughts before I spend a few days messing around with it.
I am now rolling my own blog app and I am kind of newbie to Rails 3. Even like that, in 1 week i have a blog with tags, comments, authentication with omniauth, etc.. my advise is: roll your own. I was having the same doubt and looking for pre-made solutions and I decided to start it from zero and just look for plugins for anything i need.
It goes pretty fast if you know already some rails programming and you use the right plugins. This is what i used:
Omniauth to let users be able to autenticate with facebook, twitter etc.. and leave you comments.
rails_admin: it allows you to manage your blog by going to yourapp.com/admin. It uses devise to create an Admin user (you can specify a diferent model name than user to not to mix it with the users from omniauth or from your other app) and if you have the right models and associations between them you can from there create your posts, assign them tags or categories and also delete comments etc.. its all done in an easy way. For the Text Area that you use to introduce the content of your posts you can associate it with the ckeditor just by adding to the rails_admin initializer something like:
config.model Post do
edit do
field :body, :text do
ckeditor true
end
end
end
And with the ckeditor you can introduce pictures, attach videos, format text, and so on.
Use kaminari for pagination, or you can use will_paginate if you are more used to that.
Using the blueprint framework for styling with css you will save time and have a more standar styling.
Use few jquery lines to insert/delete comments graciously.
And that's all I can remember now. And if it shouldn't interfere with the main app, i would just assign a subdomain for it. So if you go to blog.myapp.com you access to the blog and if you go to myapp.com you access to the app. And you want users from the app to interact with the blog so you should use just one app and have this 2 subdomains pointing at differents parts of the same a app.. take a look at: rails 3 - one app, multiple domains, how implement a different 'root' route for one of the domains?
That's all i can think now! let me know if i can help you in anything else.
rails_admin: it allows you to manage your blog by going to yourapp.com/admin. It uses devise to create an Admin user (you can specify a diferent model name than user to not to mix it with the users from omniauth or from your other app) and if you have the right models and associations between them you can from there create your posts, assign them tags or categories and also delete comments etc.. its all done in an easy way. For the Text Area that you use to introduce the content of your posts you can associate it with the ckeditor just by adding to the rails_admin initializer something like:
config.model Post do
edit do
field :body, :text do
ckeditor true
end
end
end

Suggestions on addressing REST resources for API

I'm a new REST convert and I'm trying to design my first RESTful (hopefully) api and here is my question about addressing resources
Some notes first:
The data described here are 3d render
jobs
A user (graphics company) has multiple projects.
A project has multiple render jobs.
A render job has multiple frames.
There is a hierarchy enforced in the data (1 render job
belongs to one project, to one user)
How's this for naming my resourses...?
https:/api.myrenderjobsite.com/
/users/graphicscompany/projects
/users/graphicscompany/projects/112233
/users/graphicscompany/projects/112233/renders/
/users/graphicscompany/projects/112233/renders/889900
/users/graphicscompany/projects/112233/renders/889900/frames/0004
OR a shortened address for renders?
/users/graphicscompany/renders/889900
/users/graphicscompany/renders/889900/frames/0004
OR should I shorten (even more) the address if possible, omitting the user when not needed...?
/projects/112233/
/renders/889900/
/renders/889900/frames/0004
THANK YOU!
Instead of thinking about your api in terms of URLs, try thinking of it more like pages and links
between those pages.
Consider the following:
Will it be reasonable to create a resource for users? Do you have 10, 20 or 50 users? Or do you have 10,000 users? If it is the latter then obviously creating a single resource that represents all users is probably not going too work to well when you do a GET on it.
Is the list of Users a reasonable root url? i.e. The entry point into your service. Should the list of projects that belong to a GraphicsCompany be a separate resource, or should it just be embedded into the Graphics Company resource? You can ask the same question of each of the 1-to-many relationships that exist. Even if you do decide to merge the list of projects into the GraphicsCompany resource, you may still want a distinct resource to exist simple for the purpose of being able to POST to it in order to create a new project for that company.
Using this approach you should be able get a good idea of most of the resources in your API and how they are connected without having to worry about what your URLs look like. In fact if you do the design right, then any client application you right will not need to know anything about the URLs that you create. The only part of the system that cares what the URL looks like is your server, so that it can dispatch the request to the right controller.
The other significant question you need to ask yourself is what media type are you going to use for these resources. How many different clients will need to access these resources? Are you writing the clients, or is someone else? Should you attempt to reuse an existing standard like XHTML and classes/microformats? Could you squeeze most of the information into Atom? Maybe Atom with some extra namespaces like GDATA does it? Or is this only going to be used internally so you can just create your own media types, like application/vnd.YourCompany.Project+xml, application/vnd.YourCompany.Render+xml, etc.
There are many things to think about when designing a REST api, don't get hung up on what your URLs look like and you should really try to avoid doing "design by URL".
Presuming that you authenticate to the service, I would use the 1st option, but remove the user, particularly if the user is the currently logged in user.
If user actually represents something else (like client), I would include it, but not if it simply designates the currently logged in user. Agree with StaxMan, though, don't worry too much about squeezing the paths, as readability is key in RESTful APIs.
Personally I would not try to squeeze path too much, that is, some amount of redundant information is helpful both to quickly see what resource is, and for future expansion.
Generally users won't be typing paths anyway, so verbosity is not all that bad.