简体   繁体   中英

Rails - ActionController::Parameters include controller value with form values

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM