Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Active Admin, Rails 4 Nested Form DELETE then INSERT has_one Model

When ever you edit a User that has_one Profile, Active admin DELETE the profile and re create it again, which makes the avatar image to be deleted by paperclip

How can i make active admin just update the nested form without deleting and re-creating it.

here is my ActiveAdmin:User Code

ActiveAdmin.register User do
  menu :priority => 2

  ## Controller
  controller do

    def update
      if params[:user][:password].blank?
        params[:user].delete("password")
        params[:user].delete("password_confirmation")
      end

      if params[:user][:profile_attributes][:avatar].blank?
        params[:user][:profile_attributes].delete("avatar")
      end

      super
    end

    def permitted_params
      params.permit user: [:username, :email, :password, :password_confirmation, :approved, role_ids: [], profile_attributes: [:first_name, :last_name, :date_of_birth, :avatar]]
    end

  end

  #Scopes
  scope :all, default: true
  scope :admins
  scope :editors
  scope :members

  ## Filters
  filter :username
  filter :email

  ## Index
  index do
    column :id
    column :first_name do |user|
      user.profile.first_name unless user.profile.nil?
    end
    column :last_name do |user|
      user.profile.last_name unless user.profile.nil?
    end
    column :username
    column :email
    column :role, :sortable => false
    default_actions
  end

  ## Form
  form :html => {:multipart => true} do |f|

    f.inputs "User Account Details" do
      f.input :username
      f.input :email
      f.input :roles
      f.input :approved
      f.input :password, hint: "leave it blank if you don't want to change it"
      f.input :password_confirmation
    end

    f.inputs "Profile Details",  for:  [:profile, f.object.profile || f.object.build_profile] do |profile_form|
        profile_form.input :first_name
        profile_form.input :last_name
        profile_form.input :date_of_birth, as: :date_select, start_year: Date.today.year-80, end_year: Date.today.year-13

        profile_form.input :avatar, :as => :file, :hint => profile_form.template.image_tag(profile_form.object.avatar.url(:small))
    end

    f.actions
  end

end

and here is what the console shows, notice that it deleted the profile record and re create it again which makes the paperclip gem to delete the already updated image.

Started PATCH "/admin/users/1" for 127.0.0.1 at 2013-08-02 01:29:09 +0200
Processing by Admin::UsersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"m9tBWsM+Jq0CWmSu2kCxCMn8xV3pgYQ0iFz5K9X5EjY=", "user"=>{"username"=>"admin", "email"=>"[email protected]", "role_ids"=>["", "", "1", "2"], "approved"=>"1", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "profile_attributes"=>{"first_name"=>"Moe", "last_name"=>"Hassan", "date_of_birth(1i)"=>"1935", "date_of_birth(2i)"=>"4", "date_of_birth(3i)"=>"4", "id"=>"58"}}, "commit"=>"Update User", "id"=>"1"}
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
   (0.3ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["user_id", 1]]
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", "1"]]
Unpermitted parameters: id
Unpermitted parameters: utf8, _method, authenticity_token, commit, id
  Role Load (0.4ms)  SELECT "roles".* FROM "roles" WHERE "roles"."id" IN (1, 2)
  Role Load (0.3ms)  SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1  [["user_id", 1]]
   (0.1ms)  BEGIN
   (0.1ms)  COMMIT
  Profile Load (0.2ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1  [["user_id", 1]]
   (0.1ms)  BEGIN
[AWS S3 200 1.692562 0 retries] head_object(:bucket_name=>"assets.goldpricenetwork.dev",:key=>"public/avatars/58/original-901301_3903423203601_1063661495_o.jpg")  

[AWS S3 200 0.305978 0 retries] head_object(:bucket_name=>"assets.goldpricenetwork.dev",:key=>"public/avatars/58/small-901301_3903423203601_1063661495_o.jpg")  

  SQL (0.3ms)  DELETE FROM "profiles" WHERE "profiles"."id" = $1  [["id", 58]]
[paperclip] deleting public/avatars/58/original-901301_3903423203601_1063661495_o.jpg
[AWS S3 204 0.261193 0 retries] delete_object(:bucket_name=>"assets.goldpricenetwork.dev",:key=>"public/avatars/58/original-901301_3903423203601_1063661495_o.jpg")  

[paperclip] deleting public/avatars/58/small-901301_3903423203601_1063661495_o.jpg
[AWS S3 204 0.255899 0 retries] delete_object(:bucket_name=>"assets.goldpricenetwork.dev",:key=>"public/avatars/58/small-901301_3903423203601_1063661495_o.jpg")  

   (2.2ms)  COMMIT
   (0.1ms)  BEGIN
  SQL (0.5ms)  INSERT INTO "profiles" ("created_at", "date_of_birth", "first_name", "last_name", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["created_at", Thu, 01 Aug 2013 23:29:12 UTC +00:00], ["date_of_birth", Thu, 04 Apr 1935], ["first_name", "Moe"], ["last_name", "Hassan"], ["updated_at", Thu, 01 Aug 2013 23:29:12 UTC +00:00], ["user_id", 1]]
   (0.3ms)  COMMIT
Redirected to http://localhost:3000/admin/users/1
Completed 302 Found in 2552ms (ActiveRecord: 5.8ms)

any solution?

like image 975
Moe Hassan Avatar asked Nov 12 '22 00:11

Moe Hassan


1 Answers

Try permitting :id attribute for profile_attributes

profile_attributes: [:id , ...]

And try remove this monkeypatch :

  if params[:user][:profile_attributes][:avatar].blank?
    params[:user][:profile_attributes].delete("avatar")
  end
like image 175
dbKooper Avatar answered Nov 26 '22 03:11

dbKooper