Ruby on Rails User Setup - ruby-on-rails

Currently, I have a 6-model ruby on rails application, that I added authlogic to.
The overall setup is
User :has_many categories, topics,messages
Categories has_many topics,
Topics has_many messages
(With and the corresponding opposite belongs_to links).
When I try to access current_user.categories.find(2), no results are returned in the controller.
Furthermore, when I try to run this
current_user.topics.find(params[:topic_id]).messages.build
Then,
#msg = current_user.messages.build(params[:message])
#msg.save
It doesn't save the user_id from the has_many.
All features of this program were working before the current_user directives were added in.
Am I making a mistake with the setup? Or with the execution?
Because the association isn't saving after the build, could I later add the user_id field in the model?
Sorry about all the questions, and thanks in advance.

I think your best bet is to go step-by-step. What does current_user return? Does the id of that user match one in your db? Does that user have any categories? Do any of them have an id of 2?
If you can isolate your problem to a single layer in your chained calls, it will be much easier to debug.

Thanks Kyle.
I've solved the problem using a filter in the model instead of using the controller to assign it on creation through association.
Current_user simply returns the record of the current user using authlogic.
I'm liking where the project is bow, and might deploy it after some visual tweaking, security, and more css :).
Callbacks and filters are amazing with whatever you are developing.
Also, if you need to get an variable from the application_controller to the model use the dollar sign ruby variable, not a class instance variable (at-sign).
Rails is so easy compared to a roll-your-own Php or sintra app.
Also, How many models are used for rails apps?

Related

rails 4- where to put user function

I am building a sample app for learning rails 4, and I'm a little confused on where I'm meant to build certain things. For example, I want to check if a user is logged in, and if so, display their account balance in the header (a partial).
Thanks to Michael Hartl's tutorial, I have a function to check a user's login status in the session helper, which is included in the application controller and can therefore be accessed in the partial.
Since the balance is tracked in the Users table, do I build a function get_balance in the Users model? Or should I create a function in the application helper? If I do build it in the application helper, is this auto-included in the application controller, or do I have to include it specifically? If I don't build the function in the model, can I still access the User object?
Thanks for your patience with a noob.
Since your users balance is a column in Users table, it is already there for you as a field (most possibly user.balance). And yes, this is where you should store it. You might use helpers for stuff that is related to general layout of your application and use combination of partial view and layout to spread it around.
Since it's already on your table, assuming your user is logged in, you could just call
current_user.balance
But it sounds like you want to add onto the data given,
I would suggest perhaps using a Rails decorator for your user model.
Basically a decorator adds an object-oriented layer of presentation logic to your Rails application.
I use the Draper Gem

Path security and before_filters rails

I am currently creating an app where users can create and apply for jobs. However as I am fairly new to rails I am facing a fairly significant security feature in that if any user knows the correct path, for example:
localhost:3000/users/user_id/apps
Then they can see any application made by any user for any job!
I am fairly sure that I need to use a before_filter to check that the current_user.id matches either the user_id found in my jobs table for each job or matches the user_id found in my applications table.
I am really not sure how to structure this though or where to apply the filter - for example is it better to create the filter in the application controller and then apply a skip_before_filter instance where needed.
Any help people can offer on contructing this code and where to place it would be much appreciated! Thanks :)
Before you start looking at authorization solutions such as cancan, a simple approach is to avoid doing
App.find params[:id]
Since an app is associated to a user and you've got current_user setup you can do
app = current_user.apps.find params[:id]
Which will only find apps associated with the user, no matter what the parameters to find.
Where cancan really comes into its own is when you need a more complicated who can do what system. For example a user might be able to edit any job they've created but view (and not edit) another set of jobs.
For example
can :manage, Project, :user.id => user.id
can :read, Project, :department => user.department
This would allow users full access to any of their projects and read access to projects in their department
Another thing about cancan is that rather than having before_filters or macros scattered around your controllers you declare the rules in one place, so it's usually easier to see what's going on. There's loads more info on the cancan wiki an a railscast too.
You are right a before_filter might be an sollution but its not the state of the art solution. Theres a railscast for that,...
http://railscasts.com/episodes/192-authorization-with-cancan/
When your using cancan but not devise you need to create the current_user helper that should return the User object of the currently logged in user...

Authentication with Ruby on Rails & Devise

I am about to build a new site in ruby on rails for residents at my college.
The site will allow residents to change their passwords for the college-firewalls (which means there are certain requirements).
On the site, each resident will have an account with a number of data assigned to it, and for this I need some authentication.
I've been studying Devise for almost the entire day now, but im starting to wonder if I have a too complicated task, to complete it with Devise.
Problem is, I need the passwords to be stored with DES-encryption, something Im not sure if Devise can handle.
Another thing is, users can't make their own profile. Admins will do that (to ensure correct data), which means that user-creation is not the default one. Since there are no controllers for this, is it even possible to do it that way?
I'm not sure if I should keep on going with Devise, or bite the bullet and write it all from scratch instead. Some opinions would be appreciated.
This page on the Devise wiki ( https://github.com/plataformatec/devise/wiki/How-To:-Create-a-custom-encryptor ) tells you how to set up a custom encryptor.
To make it so that admins create a user, remove the :registerable module from the User model. Then add a user resource to your app, example:
scope 'admin' do
resources :users
end
Set up the new/edit pages with your profile fields, etc., normal rails programming.
For an example using CanCan to control access to the users resource, have a look at this post: http://zyphmartin.com/blog/manage-users-with-devise-and-cancan.
If devise does not exactly do what you need, maybe this recent webcast from Ryan Bates will help you.

Ruby on Rails - Create Entity with Relationship

I'm new to rails, so be nice.
I'm building a "rolodex" type application, and this question is about the best way to handle creating an entity along with several relationship entities at the same time.
For (a contrived) example:
My application will have a Person model, which has_one Contact_Info model. On the create.html.erb page for Person it makes sense for the user of my appliction to create the person, and the contact_info at the same time.
It doesn't seem right to include details for creating a contact directly in the create view/controller for person. What's the rails way to handle this?
Using nested attributes is the most common way to do this.
The actual documentation is here.
You want to use "Nested Forms". There is a great example of them in this blog post.
I'm also noob, but I had a similar issue with an app. I was using a tutor at the time and he basically said it was a good example of rails being opinionated. It sounds like you want to take the create action for two different models at the same time, which may be possible but probably very hard. Id suggest considering whether your data model could be modified, or find a way to make an acceptable user flow while collecting the data in different forms.
Update: while writing this the technical answer came in. Keep in mind, its perfectly okay to take the easy route if doing so helps you get the app out the door, and especially while you're still new.

Changing/Upgrading Existing Models

I starting building my app using nifty-generators for the user authentication because I'm new to Rails and it was the easiest approach. Now, we're looking to launch the app and I want to implement the popular Restful Authentication because we need some of the features it offers.
I've never upgraded an existing model in this way, and I'm wondering what the best approach would be. Should I strip out the user model-related stuff? Or will Restful Authentication just overwrite the commonly name items? Of course, I can go into the app and make tweaks based on any changes.
Generally, how would more experienced Rails coders approach this?
Thanks!
You might want to check out Authlogic instead. There's a good railscast episode where he implements Authlogic with nifty generators.
I would add another model and relate that via an has_one-relation..
f.e. adding a Account-Model (if your user-model already exists)
class Account << AR
belongs_to :user
end
class User << AR
has_one :account
end
If you've got a fair amount of tests, there shouldn't be an issue. Your suite will let you know if you've done something wrong.
Personally I would implement Restful Auth, by hand, on another project. Play around with it until you understand how it affects your user model, then copy over the code and any migrations you need.
A nice tutorial on Restful Auth and some cool extensions is here

Resources