Rails association - how to add the 'has_many' object to the 'owner' - ruby-on-rails-3

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

Related

is it possible for current_user to be initializer, in rails 3?

Is it possible to use something like current_user or User.current in the initializers? I've tried something like
Something = Something::Some.new configure do |something|
something.somethingelse = current_user.key
end
but it states it can't find the key but I know that key is a column in User table. I can do something = current_user.key or something = User.key in under model or controller and it works fine.
current_user is usually set in the application_controller of your application. If you use a gem like Devise to handle user authentications for example, they take care of setting such method for you.
The initializers' code is executed when you launch your application on your server (local machine or remote server), therefor you understand that a "current_user" (understand a "logged in" user) simply does not exists (yet).

How to properly scope User attributes in rails

How to achieve simple scoping in your views such as:
<% if #user.admin %>
where "admin" is the following scope in user.rb:
scope :admin, where(role: "admin")
there is a column Role which is a string in the Users table
I've done the same thing before with another Model (but not a devise user model) to which I could later call
<% if objective.completed %>
right after calling an each method in the objectives.
However
When I do the exact same thing to a user model I get an
undefined method `admin' for #<User:0x00000107e39038>
How could I make it work? I've been digging for hours.
For a no scope workaround try:
<% if #user.role == "admin" %>
You simply can't use scopes this way. Scopes are used as class methods, so if you run
User.admin
it returns list of users matching given condition. What you need is an instance method. Add it to your user.rb file:
def admin?
admin == 'admin'
end
and you will be able to use it in your view:
- if #user.admin?
anyways, you should definitely reconsider storing roles as string in users table. Try to create another table called roles.
Scopes are usually class level methods, having said that, how can you access it with an instance. I think, that is why the error says undefined method.

Why doesn't CanCan respect my rule?

I need to restrict users to only access their shipping list items by 'supplier_id '. I know I can use 'accessible_by' to add a 'where' clause. But if I forget to add the accessible_by scope to my query, in the following controller, in action index, the user can read any list.
class SupplierShippingListsController < ApplicationController
load_and_authorize_resource
def index
#shipping_lists = SupplierShippingList.where(:supplier_id => params[:supplier_id])
authorize! :read, SupplierShippingList
end
end
I defined this rule first, hopping the instance would be checked against my hash but it doesn't, as if :supplier_id was pointless.
can :read, SupplierShippingList, :supplier_id => user.company_id
So I tried a block with a random value to make it fail the authorization, but the user can still access the action.
can :read, SupplierShippingList do |list|
list.supplier_id == 17
end
Is there some hidden thing to set?
EDIT
I also tried
authorize! :read, #shipping_lists
with no avail.
Index actions will ignore the block, so your second example will not work. Your best bet for relatively simple abilities like this is to use a hash of conditions like your first example. But load_and_authorize_resource will automatically load #supplier_shipping_lists for you. Your index action as shown will overwrite the variable and make the 'load' portion of 'load and authorize resource' pointless. You should remove your index action and let CanCan do the loading for you. If you don't override the instance variable, you should see what you expect as long as you use the hash of conditions.
Also, you don't need to manually call authorize! either. That is the 'authorize' part of load_and_authorize_resource. You need to just let CanCan do the work. When you enter your index action, the instance variable will either already be initialized, but will be empty if you don't have the authority to view any lists.
Since you're using load_and_authorize_resource you don't have to do anything. In your index action it should find all of the supplier_shipping_lists that correspond to the user company if you're using the can :read, SupplierShippingList, :supplier_id => user.company_id. If that isn't working, do you have any other rules being applied to the SupplierShippingList?

Get current user in a model in Rails3

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.

Ruby on rails tutorial: where is the user create view created?

Trying to follow along the ruby on rails 3 tutorial, I've completed the sign up process (through chapter 8) but nowhere has a user view: create.html.erb been created. Since 'create' is a section in the user controller, there needs to be a corresponding 'create.html.erb' file in views/users so I get a 'missing template' error when I try to use the tutorial form to create a new user.
Where does the tutorial create the create.html.erb file? I have paged through the tutorial a couple of times and can find no trace of it.
Thanks in advance for any help. --Fred
I am editing the question because for some reason the site will not let me add a comment below the responses to my question.
In UsersController... I have copied the following code directly out of the tutotrial:
def create
#user = User.new(params[:user])
if #user.save
#do something here
else
#title = "Sign up"
render = 'new'
end
end
I get: missing template users/create with {:locale=>[:en, :en].....
So if It is not a missing template issue, what is it?
create is an intermediary action, it does not require a view. in your create function make sure you do a redirect_to or a render view to something. here you can also populate a flash with messages corresponding to the success of the function (validation errors, succes for save etc)
When you create a new record, you actually call the new method, which does have an associated view called new.html.erb. The create method is called when you hit the "submit" button in the new.html.erb view, and there is no view for create - it is just a method that runs without a view.
Same applies for the update method which doesn't have it's own view, but which is "friends" with the edit action, whose associated view is called edit.html.erb.
Delete method is different