0

I have a session variable (user_id) that I'd like to include as a foreign key on a record the user is inserting. I have the form values all coming through the form submit to my controller's entity.update(params) method without a problem using the default params definition. That code looks like

 def brand_params
    @brand_params = params.require(:brand).permit(:name, :brand_type, :profile_id)
  end

The update method looks like

if @brand.update(brand_params)
        format.html { redirect_to @brand, notice: 'Widget was successfully updated.' }
        format.json { render :show, status: :ok, location: @brand }
      else
        format.html { render :edit }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
      end

Now I'd like to append the :profile_id session variable to the @brand_params and following other threads here, I've tried a setter method:

def set_brand_params(key, val)
    if @brand_params != nil
      @brand_params[key] = val
    end
  end

However, calling this, @brand_params is always nil. Trying to directly add to the brand_params hash doesn't work because it's a better method. If there's a better way to meet this (I'd assume common) use case, I'm all ears! Otherwise, I'd like to know why the var is always nil though in this context, at least the brand_params method sees it as defined and with value. I got this solution in Adding a value to ActionController::Parameters on the server side

Here is the update method as requested:

def update
    puts "update"
    set_brand_params("profile_id", session[:prof])
    respond_to do |format|
      if @brand.update(brand_params)
        format.html { redirect_to @brand, notice: 'Widget was successfully updated.' }
        format.json { render :show, status: :ok, location: @brand }
      else
        format.html { render :edit }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
      end
    end
  end
3
  • If you are using set_brand_parmas before any call of brand_params yes, @brand_params is undefined (nil). Commented Oct 24, 2014 at 1:24
  • Yes, if I move the @brand_params variable to the constructor (here new()) it's not nil so that's the answer! I'm still unclear on the best practice because now this protected var is public... but good enough. Commented Oct 25, 2014 at 23:40
  • Please, can you edit the question and add the whole method update? Commented Oct 26, 2014 at 0:26

1 Answer 1

0

I'm not agree with merge your data with the params. Because you must permit only the fields you expect your user update. In this case you don't want the user update profile_id on brands, and that is a security best practice.

Then brand_params must be:

def brand_params
  @brand_params = params.require(:brand).permit(:name, :brand_type)
end

Your method update may look by this:

def update
  @brand = Brand.find(params[:id])
  @brand.assign_attributes(profile_id: session[:prof])
  respond_to do |format|
    if @barnd.update(brand_params)
      format.html { redirect_to @brand, notice: 'Widget was successfully updated.'}
      format.json { render :show, status: :ok, location: @brand }
    else
      format.html { render :edit }
      format.json { render json: @brand.errors, status: :unprocessable_entity }
    end
  end
end

You don't need the method set_brand_params at all.

If this don't do the trick, please publish the entry controller, and I hope we find the issue.

edit: add respond_to.

Sign up to request clarification or add additional context in comments.

2 Comments

After I seen your code, I assume you have a before_filter or before_action at your controller, and it sets the @brand variable, like I do at the start of my update method. In this case replace the set_brand_params method with @brand.assign_attributes(profile_id: session[:prof])
Yes, @Alejandro, this worked. By using assign_attributes and removing from the params, this is much more secure. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.