Question

I have an Account model with a single attachment intended to be used for a logo, called logo. I have set logo in the parameters list, form is multi-part but I keep getting an unpermitted parameters :logo in the output during this request:

Everything is saving, except the logo which was added later.

Started PUT "/account" for 127.0.0.1 at 2014-05-13 21:43:57 +1200
Processing by AccountsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"w5jFIZ/IMjvSfGllNoLEoMiboFjGnEE3jgIRERTTSBU=", "account"=>{"name"=>"Company Name", "logo"=>#<ActionDispatch::Http::UploadedFile:0x000001010877b0 @tempfile=#<Tempfile:/var/folders/k1/v289qztd2219jxmfk_x42x8m0000gn/T/RackMultipart20140513-2296-12w270c>, @original_filename="rails.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"account[logo]\"; filename=\"rails.png\"\r\nContent-Type: image/png\r\n">}, "commit"=>"Save Changes"}
  Account Load (16.5ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."full_domain" = 'ezypay.leaveme.dev' LIMIT 1
  CACHE (0.0ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."full_domain" = 'ezypay.leaveme.dev' LIMIT 1
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."account_id" = 1 AND "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Unpermitted parameters: logo
   (0.1ms)  begin transaction
  User Load (10.6ms)  SELECT "users".* FROM "users" WHERE "users"."account_id" = 1 AND "users"."account_id" = ? AND "users"."admin" = 't' ORDER BY "users"."id" ASC LIMIT 1  [["account_id", 1]]
  User Exists (0.3ms)  SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'cmcguff@gmail.com' AND "users"."id" != 1 AND "users"."account_id" = 1) LIMIT 1
  User Exists (0.5ms)  SELECT 1 AS one FROM "users" WHERE ("users"."remote_id" = 'bureau' AND "users"."id" != 1 AND "users"."account_id" = 1) LIMIT 1
   (0.1ms)  SELECT COUNT(*) FROM "accounts" WHERE (full_domain = 'ezypay.leaveme.dev' and id <> 1)
  SQL (465.4ms)  UPDATE "accounts" SET "name" = ?, "updated_at" = ? WHERE "accounts"."id" = 1  [["name", "Company Name"], ["updated_at", Tue, 13 May 2014 09:43:58 UTC +00:00]]
   (2.4ms)  commit transaction

The form is set up like this:

<%= simple_form_for @account, :url => { :action => 'update' }, :html => { :method => :put, :multipart => true  } do |f| %>
  <%= f.input :name %>
  <%= f.input :logo, :as => :file %>
  <%= submit_or_cancel :action => 'show' %>
<% end %>

The Accounts controller:

class AccountsController < ApplicationController
  inherit_resources

  before_filter :authenticate_user!, :except => [ :new, :create, :plans, :canceled, :thanks]
  before_filter :authorized?, :except => [ :new, :create, :plans, :canceled, :thanks]
  before_filter :build_user, :only => [:new, :create]
  before_filter :load_balances, :only => [ :dashboard ]
  before_filter :load_billing, :only => [ :billing ]
  before_filter :load_subscription, :only => [ :billing, :plan ]
  before_filter :load_discount, :only => [ :plans, :plan, :new, :create ]
  before_filter :build_plan, :only => [:new, :create]
  skip_before_filter :collect_billing_info

  def new
    # render :layout => 'public' # Uncomment if your "public" site has a different layout than the one used for logged-in users
  end

  def create
    @account.affiliate = SubscriptionAffiliate.find_by_token(cookies[:affiliate]) unless cookies[:affiliate].blank?

    if @account.save
      flash[:domain] = @account.domain
      redirect_to thanks_url
    else
      render :action => 'new'#, :layout => 'public' # Uncomment if your "public" site has a different layout than the one used for logged-in users
    end
  end

  def update
    if resource.update_attributes(params[:account].permit(:name))
      flash[:notice] = "Your account has been updated."
      redirect_to redirect_url
    else
      render :action => 'edit'
    end
  end

  def plans
    @plans = SubscriptionPlan.order('amount desc').collect {|p| p.discount = @discount; p }
    # render :layout => 'public' # Uncomment if your "public" site has a different layout than the one used for logged-in users
  end

  def billing
    if request.post?
      result = if params[:stripeToken].present?
        @subscription.store_card(params[:stripeToken])
      else
        @address.first_name = @creditcard.first_name
        @address.last_name = @creditcard.last_name

        (@creditcard.valid? & @address.valid?) && @subscription.store_card(@creditcard, :billing_address => @address.to_activemerchant, :ip => request.remote_ip)
      end

      if result
        flash[:notice] = "Your billing information has been updated."
        redirect_to :action => "billing"
      end
    end
  end

  def plan
    if request.post?
      @subscription.plan = SubscriptionPlan.find(params[:plan_id])

      if @subscription.save
        flash[:notice] = "Your subscription has been changed."
        SubscriptionNotifier.plan_changed(@subscription).deliver
      else
        flash[:error] = "Error updating your plan: #{@subscription.errors.full_messages.to_sentence}"
      end
      redirect_to :action => "plan"
    else
      @plans = SubscriptionPlan.where(['id <> ?', @subscription.subscription_plan_id]).order('amount desc').collect {|p| p.discount = @subscription.discount; p }
    end
  end

  def cancel
    if request.post? and !params[:confirm].blank?
      current_account.destroy
      sign_out(:user)
      redirect_to :action => "canceled"
    end
  end

  def thanks
    redirect_to :action => "plans" and return unless flash[:domain]
    # render :layout => 'public' # Uncomment if your "public" site has a different layout than the one used for logged-in users
  end

  def dashboard
  end

  protected

    def resource
      @account ||= current_account
    end

    def build_user
      build_resource.admin = User.new unless build_resource.admin
    end

    def build_plan
      redirect_to :action => "plans" unless @plan = SubscriptionPlan.find_by_name(params[:plan])
      @plan.discount = @discount
      @account.plan = @plan
    end

    def redirect_url
      { :action => 'show' }
    end

    def load_balances
      @your_balances = current_user.visible_leave_balances
    end

    def load_billing
      @creditcard = ActiveMerchant::Billing::CreditCard.new(params[:creditcard])
      @address = SubscriptionAddress.new(params[:address])
    end

    def load_subscription
      @subscription = current_account.subscription
    end

    # Load the discount by code, but not if it's not available
    def load_discount
      if params[:discount].blank? || !(@discount = SubscriptionDiscount.find_by_code(params[:discount])) || !@discount.available?
        @discount = nil
      end
    end

    def authorized?
      redirect_to new_user_session_url unless self.action_name == 'dashboard' || admin?
    end

    def permitted_params
      params.permit(:plan, :account => [ :name, :domain, :logo, :admin_attributes => [ :name, :email, :password, :password_confirmation ] ])
    end

end

The Account model has logo set up as :

has_attached_file :logo, styles: {
    thumb: '100x100>',
    square: '200x200#',
    medium: '300x300>'
}
validates_attachment_content_type :logo, :content_type => /\Aimage\/.*\Z/

I'm really not sure what else to check here?

Was it helpful?

Solution

In your update method you are not actually using your permitted_params method. The only attribute you permit is :name. You should change this method to allow logo also:

def update
  if resource.update_attributes(params[:account].permit(:name, :logo))
    ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top