Get current user in a model in Rails3 - ruby-on-rails-3

I am using ActiveAdmin. I need to store the User that created or updated every record.
So I added user_created_id and user_updated_id to every model.
On before_save I want to store the information about current_admin_user. The problem is that I cannot access current_admin_user in a model.
Is there a way to do that without breaking MVC?
I found this: http://rails-bestpractices.com/posts/47-fetch-current-user-in-models
But I am not sure if it is safe.
Any help?

Do it in controller (it's the reason that controller exist) before save:
def create
#my_model = MyModel.create params[:my_model]
#my_model.user_created = current_user
#my_model.save
end
The same with the update method.

Related

Wicked Rails Gem Help Wiring Up

I want to do a multi-step form for taking in new information. One page I want to collect name/contact info, the next page I want to collect medical history, the third page demographic information.
I've installed the Wizard gem and generated a dedicated controller. All of the tutorials I've seen on it apply to devise and the signup process so I'm a little bit lost on the controller actions and the instance variables and how I should be writing them.
Was wondering if anyone has a tutorial other than a sign-up one that could maybe help me along in learning how to get this all wired up.
Any pointers or assistance is appreciated.
EDIT:
I think my problem is in the controller for my wizard.
In the show and update actions the demo shows to declare the variable of
#user = current_user
That's great, but it's a helper method that I don't need. I need to create a patient, store the patient_id in a session which I do in my create action in my main patients controller. Then somehow pass that over to the patientsteps controller.
Here's what I've tried in patientsteps
class PatientstepsController < Wicked::WizardController
before_filter :authenticate_user!
steps :medical, :summary
def show
#patient = Patient.find(params[:patient_id])
render_wizard
end
def update
#patient = Patient.find(params[:id])
#patient.attributes = params[:patient]
render_wizard #patient
end
end
When I do this, I get cannot find a patient without and ID. I understand that I'm doing this wrong, but I'm not sure how to pass in the patient_id that was created in my patients controller create action.
Patients Controller Create:
def create
#patient = Patient.new(params[:patient])
if #patient.save
session[:patient_id] = #patient.id
redirect_to patientsteps_path, notice: "Patient was successfully created."
else
render :new
end
end
In your show action, instead of params[:patient_id] you should use session[:patient_id], because the id of the patient is stored in the session, not in the params hash.
Then in the update action, you will receive the patient id in params[:patient_id], not [:id], because wicked uses params[:id] to identify which step the wizard is on.

Rail3 | How to create standard route/action for ALL controllers?

Well, DRY! So i thought it should be easy to add a new action (like the existing new, edit) to all my controllers (in my case copy). But how do you setup a new route for ALL controllers?
Without going in to 'loops' (i.e. %w().each ...) inside the routes.rb ?
I mean, we want DRY right? So you don't want copy your action inside the routes file for each resource. I guess you should be able to extend the default actions/routes (index, new, edit,etc.) easy?
Thanks!
AFIK no way to do this by default. You could monkey-patch resources to include this functionality:
https://github.com/rails/rails/blob/b229bc70e50ec0887c5bb3aaaa9c6ee8af054026/actionpack/lib/action_dispatch/routing/mapper.rb#L982
...but my hunch is you would be better off re-considering whether this functionality can be created another way, since what you want to do is "off the Rails".
One option is create a CloneController#new that accepts a model and id and creates a clone. This seems like it would be drier, and wouldn't require you to pepper a gazillion "clone_article" "clone_blog" "clone_user" paths all over the place.
Obviously you would want to carefully white-list the models/ids that can be passed in.
Looking through the source there isn't a way to add to the default actions for a resource.
But, as #juwiley says, the methods resources :item is just a shortcut for creating a load of member and collection methods.
All you need to do is something like this
class ActionDispatch::Routing::Mapper
def resources_with_copy(*resources, &block)
block_with_copy = lambda do
block.call
member do
post :copy
end
end
resources(*resources, &block_with_copy)
end
end
Then in your routes.rb just say
resources_with_copy :items
resources_with_copy :posts do
member do
post :share
end
end
...

Rails association - how to add the 'has_many' object to the 'owner'

In my app, a user has many score_cards and a score_card belongs to a user
The question is, whenever I create a new score_card, ie, ScoreCardsController.create gets called, how do I add this newly created score_card to the current_user (I'm using devise, so current_user is a valid User object).
current_user.score_cards << score_card
OR
score_card.user = current_user
score_card.save
Use the association builder method:
current_user.score_cards.build(params[:score_card])
Alternatively to build you can use create or create! if you don't care about the validations in the controller.
I'm going to throw this out there in case anyone is looking for a way to add multiple objects to an associated object:
score_cards = ScoreCard.all
current_user.score_cards << score_cards
No need to current_user.save

Rails 3 saving a record issue

I have been working with Rails 3.0.5 and Ruby 1.9.2 and I have noticed that a new record doesn't get saved or isn't available for use instantly.
For example
def create
#some_record = Pool.new(params[:pool])
#some_record.users.push(current_user)
if params[:commit] == "Add More"
#some_record.save
#some_record.do_something
elsif params[:commit] == "Save"
do_something_else(params)
elsif params[:commit] == 'Cancel'
redirect_to user_url(current_user)
end
redirect_to some_other_url(current_user)
end
So when I save the record and call some_record.do_something the saved object isn't available instantly. current_user.some_records doesn't contain the newly added record but current_user.some_records.all displays the newly saved record. However on the console I am able to view the newly created record with current_user.some_records.
I'm sure I am missing something fundamental to Rails 3. I have also tried the same with current_user.some_records.build(params[:some_record] and I have the same problem. Does Rails 3 save the object instantly or is there some kind of delayed write/save because the same problem does not occur with Rails 3.0.3.
Also I am not using an authentication plugin like authlogic/devise and I simply save the current_user object to the session. I am not sure what I am doing wrong. WOuld appreciate any help?
Its also a many-to-many association between some_record and users
current_user.some_records
does not contain the newly added record because you did not save the operation after assigning #some_record.users.push(current_user).
All you have to do is to add .save after the assignment and it should work.
The model structure is not clear from your question but let's assumed that current_user belongs_to some_records
To force a database read try this:
current_user.some_records(true)
By default forcereload = false, to override this you should pass true

How to access devise current_user from model

Just start to develop with devise for my app authentication, however running into trouble with accessing current_user from a model. I have no problem accessing this from a controller.
For my scenario I need to get the current user id to keep track who has edit the blog post, which I save the user id with before_save filter.
Appreciate your help!
Thanks
You can only pass it down in a parameter.
class SomeModel
def my_nifty_method(user)
end
end
in controller:
class SomeModelsController < ApplicationController
def some_method
sm = SomeModel.new
sm.my_nifty_method(current_user)
end
end
You should be able to do this in your model. 'c' here being the model object and setting it's user_id attribute before create, or save in your case.
before_create {|c| c.user_id = Authorization.current_user.id}
I'm somewhat new to RoR so be warned.
Why are you trying to access to that method in the model?
You can access to the ID attributes via self.id (within the model)