Nick Gallimore
Nick Gallimore

Reputation: 1263

Changing a value on a record in Ruby on Rails Controller

I have the following code in my controller and I am wondering how I might add the current_user.id to the ingredient. I am new to ruby and am still learning the syntax, so any help would be greatly appreciated.

def create
  @ingredient = Ingredient.new(ingredient_params)
  @ingredient.user_id = @decoded_auth_token.id

  if @ingredient.save
    render json: @ingredient, status: :created, location: @ingredient
  else
    render json: @ingredient.errors, status: :unprocessable_entity
  end
end 

private

# Only allow a trusted parameter "white list" through.
def ingredient_params
  params.require(:ingredient).permit(:title, :quantity, :unit)
end

Upvotes: 0

Views: 46

Answers (1)

jvillian
jvillian

Reputation: 20253

I would suggest:

def create
  @ingredient = current_user.ingredients.new(ingredient_params)

  if @ingredient.save
    render json: @ingredient, status: :created, location: @ingredient
  else
    render json: @ingredient.errors, status: :unprocessable_entity
  end
end 

That, naturally, assumes that User has_many :ingredients and Ingredient belongs_to :user.

BTW, I don't know why you have a $ in front of $current_user.id. What is that all about?

Based on your comment, I suspect you're going about things the wrong way. Presumably, you have:

class IngredientsController < ApplicationController
  ...
end

So, in ApplicationController, you could either (1) save your token to an instance variable, in which case it would be available in IngredientsController or (2) save it to the session, in which case it would also be available to IngredientsController.

I think it's not great to have current_user represent a token. That could lead to confusion for the future you. If I were you, I'd name the token variable something like, oh, I don't know, say, autenticated_token or even just token. Then, I would use current_user to hold an actual User instance (that you look up, presumable, using the token) so that you can do your current_user.ingredients.new(ingredients_params) business.

Also, I don't know what your design parameters are. But, I would speculate that you want to have User and Ingredient have a many-to-many relationship. Otherwise, you're going to end up with a lot of Ingredient records with the same name (like, 'egg') - assuming, naturally, that a lot of users have egg ingredients. Just a thought.

Based on your edit, I see you've changed:

@ingredient.user_id = $current_user

to:

@ingredient.user_id = @decoded_auth_token.id

I would guess that @decoded_auth_token.id != current_user.id. If you're @decoded_auth_token has a user_id, I would guess that you would want to use that, instead. Something like:

@ingredient.user_id = @decoded_auth_token.user_id

I suppose if Token belongs_to :user (or whatever your token class name is), then you could do:

@ingredient = @decoded_auth_token.user.ingredients.new(ingredient_params) 

But, then I think you're getting sideways with the Law of Demeter. And you never want to get sideways with the Law.

I still prefer:

@ingredient = current_user.ingredients.new(ingredient_params) 

But I suppose that's a matter of personal preference.

Upvotes: 2

Related Questions