complex mongoid rails model associations - ruby-on-rails

I am using devise as the user management system and planning to use CanCan for more advanced permission settings.
I want to build a regional discussion board,I have the follwing models
User model
City model
Talk model
every registered user can create a city and then a temporary edit permission will be given, however the admins controls everything and can revoke the permission of the one who created the city. As for the Talk model, users can only create or delete messages using ajax.
E.g. http://localhost:3000/nyc/ ==> to list all talk messages
http://localhost:3000/nyc/new ==> to create talk messages
How can I relate all these relationships via mongoid?
And How do I set the routes.rb file?

You can use add association between your city and talk like that :
Class City
include Mongoid::Document
has_many :talks
end
class Talk
include Mongoid:Document
belongs_to :city
end
See the documentation about relation on mongoid : http://mongoid.org/docs/relations.html

Related

How to create and organize an admin to have access to features other than Users in Rails

Rails newbie: I currently have a basic app where Customers(users) have many points (customer model and points model). And I want an admin user (new model) to have the ability to add points to the customer.
-The customer enters their phone number (#index route).
-If the customer is not found, they will be brought to a signup page (#new/#create route).
-If customer is found in the database, their profile will show (#show route).
Now on this page, I want to be able to have an admin passcode, which once entered, gives access to adding points. I also want to keep track of which admin user, gives which customer points on a different page.
How would the schema look like with the admin user? How would I give it access certain access to features like adding points. (I assume I'm going to have to create a helper method for checking if admin is logged in, and keep track of that somehow, maybe with sessions?)
class Customer < ActiveRecord::Base
has_many :points
end
class Point < ActiveRecord::Base
belongs_to :customer
end
class Admin < ActiveRecord::Base
#??? (my best guess is has_many :points, has_many :customers)
end
www.loyalty-app.herokuapp.com
I think the best way is to not have a special admin class and just make admins a type of customer (or user). Then use a gem like cancan or access granted (I prefer access granted) to handle what the different types of users can do.

Rails user configurable migrations through views

I'm making a business administration Rails app.
Is there any info available on how I can enable admin users to add a new field to a table? Behind the scenes this would generate and run the migration and I guess some metaprogramming to include the field in the index, show and _form.html.rb views..
You can't run migrations like that, but you can solve the problem.
The answer is here
403-dynamic-forms
If you con't have a subscription, get one. Railscasts is gold for any rails developer
Basically you make a table in the database for the fields to a model.
For instance
class Product
has_many :product_fields
end
class ProductFields
belongs_to :product
end

Support multiple models with Sorcery or Authlogic gems?

I have users and contacts.
Users sign into their account and can create address books from which they add contacts to.
If they share something with a contact that contact needs to login to view it.
Users are unique in the db (stored in users table) and contacts are stored in the contacts table and are only unique per a given address book.
I'm currently using the Sorcery gem for users, which is working great. However, how can I extend this to support authentication for contact to login?
I've read a bit into doing this via STI or polymorphic setup, but unclear on what the general pattern is for something like this.
Can I simply have both models use Sorcery? Or is that an anti-pattern?
Thanks in advance!
Why are you using a separate model for contacts? Why not just set up a self-join like:
has_many :contact_entries, :class_name => "ContactEntry"
has_many :contacts, :through => :contact_entries
Your user table would look the same, but you would have a join model like:
class ContactEntry < ActiveRecord::Base
belongs_to :user
belongs_to :contact, :foreign_key => "contact_id", :class_name => "User"
end
Which would have a user_id and contact_id field.
Update
Okay, I see your issue now. I don't think this will be possible with sorcery, at least not without making substantial edits to sorcery itself. Sorcery defines a single authenticatable model in the file initializer.rb.
Authlogic, however, can be brought into any model via "acts_as_authentic", so it is a plausible solution to your needs. The drawback is that authlogic doesn't seem to be actively developed. It had a fair amount of activity 10 days ago, however, so it's definitely worth looking in to.

Devise Cancan registration for Users and Companies

In Rails 3 application I have 2 logical entities - User and Company.
I'd like to have 2 different forms for sign up(for users and for companies). Also, will be great to have one login form for both of them.
What I have now - configured Devise+Cancan for User model with two roles(user, company), so I have now "/users/sign_in" and "/users/sign_up".
I'd like to have following urls in my application:
/login
/users/signup
/companies/signup
One other question is how to organize relationship between User and Company, should the company inherited from User or I shoud use aggregation - User has_one Company ? I prefer second variant and plan to user user.company with cancan user role = "company".
Please help me with it. Thanks.
You can have multiple models in devise. You can add a company as well.
rails generate devise company
This will get you the url you mentioned.
Regarding the relationship between User and Company It's common to use:
class User < ActiveRecord::Base
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :users
end
You have to add a company_id column to the User model in a migration to make this happen. There is no inheritance then. Users and companies are treated completely separate. But you are able to access user.company and company.users.

Handling different user types in Rails

I'm designing an application that has two [three including administrators] user types: Buyers and Sellers. When a user signs up, it's assumed that they're signing up to simply purchase something [a Buyer account]. However, if they wish to become a Seller, there should be an option for them to post their items for sale, [become a Seller]. This becomes important, as users can switch back and forth between account types.
Of course, a Seller can buy items as well.
The problem
The problem I'm facing is that Sellers have profile pages where buyers can go to view their items for sale, whereas Buyers do not. However, both user types have a My Account page that they can use to update their information.
Possible design choices
Single table inheritence
class User < ActiveRecord::Base
has_one :profile
end
class Seller < User
has_many :sale_items
end
class Buyer < User
# nothing here.. I guess this is the "default" user type
end
I thought about this approach because then I could clearly separate the user types. For example, the show page for each user is clearly separated. However, this could lead to repeated code in each controller, and introduce a problem when switching between user types.
Just use declarative_authorization or CanCan to add functionality to the base user type
class User < ActiveRecord::Base
has_one :profile
has_many :sale_items # only for Sellers
# if the user is a seller, allow them to add sale_items
end
I thought of this approach because a Seller is basically a Buyer with additional functionality, such as posting items for sale. This could lead to a lot of view logic, though. For example if #user.role == "seller" render _some_seller_partial. I also don't like the idea of checking for a hard coded string in the view. Well, I guess I could do if #user.seller?
Other design choices?
I'm really interested in hearing how other people would model this application. I've been thinking about this for a couple days now.
I would use the second option, but with declarative_authorization instead of cancan, and I'd use the role_model Gem to store the role in the user model.
class User < ActiveRecord::Base
has_one :profile
has_many :sale_items # only for Sellers
# if the user is a seller, allow them to add sale_items
# t.integer :roles_mask , :default => 0 # for role_model
end
declarative_authorization is a bit more powerful than CanCan, and I found it to scale better once a project needs more / more complex roles..
If you store your roles using the role_model Gem, it stores them as a bitmap in the roles_mask attribute.
This means that a user can have many roles, e.g. can be a Seller and a Buyer at the same time, and an Admin or Moderator if you like.
See:
http://railscasts.com/episodes/188-declarative-authorization
http://railscasts.com/episodes/189-embedded-association
http://railscasts.com/episodes/192-authorization-with-cancan
http://railscasts.com/episodes/193-tableless-model
And:
http://everydayrails.com/2011/10/06/rails-authorization.html
http://www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/
I would pick the cancan option. Is a wonderful gem, well documented, easy to use, actively mantained, and you have lots of tutorials (since it a gem created by Ryan Bates, from Railscasts, you can be sure that you have an episode for it)
I would go with the cancan option, and use the draper gem for the view logic. There are Railscasts for both gems.
http://railscasts.com/episodes/286-draper

Resources