Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 4.1 enum support #1993

Closed
dmilisic opened this issue May 21, 2014 · 44 comments
Closed

Rails 4.1 enum support #1993

dmilisic opened this issue May 21, 2014 · 44 comments
Assignees
Milestone

Comments

@dmilisic
Copy link

Rails 4.1 introduced enum attributes which don't behave well with RailsAdmin.

RailsAdmin (v 0.6.2) threats enum attributes as integers by default. This can be "fixed" by adding method to the model, ie.

enum status: [ :active, :archived ]
def status_enum
  self.class.statuses.to_a
end

There is another issue - creating or updating record raises:

ArgumentError in RailsAdmin::MainController#new 
'1' is not a valid state

Obviously the controller got '1' as a string value which doesn't match any of the states ('active', 'archived'), nor state as integer (0, 1).
The quick fix might look like:

def status= value
  if value.kind_of?(String) and value.to_i.to_s == value
    super value.to_i
  else
    super value
  end
end

It works, but isn't nice. Especially when you have multiple enum attributes.

Looking forward to support for ActiveRecord::Enum out of the box.

@dmilisic
Copy link
Author

Hope this gist helps someone - just put in in config/initializers and RailsAdmin will recognize ActiveRecord enums

https://gist.github.com/dmilisic/38fcd407044ace7514df

@jessieay
Copy link

jessieay commented Jun 5, 2014

This just got us out of a bind with Rails Admin and ActiveRecord enums. Thank you so much for the gist!

@kenchung
Copy link

kenchung commented Jun 6, 2014

I put rails_admin_active_record_enum.rb file in the config/initializers but it's not creating the necessary method handlers. Any help? I am using Rails 4.1.1 with Ruby 2.1.2.

@jessieay
Copy link

jessieay commented Jun 6, 2014

Did you restart your server? You need to restart in order for the file to be picked up by Rails Admin

@jessieay
Copy link

jessieay commented Jun 6, 2014

Also, for context on what my model looks like:

class User < ActiveRecord::Base
  ROLES = [:learner, :admin, :mentor]
  enum role: ROLES

  def role_enum
    ROLES.each_with_index.to_a
  end
end

Did not need to any any special configuration to the role field in my rails_admin config file once I had the gist linked to above saved in config/initializers/rails_admin_active_record_enum.rb

@kenchung
Copy link

kenchung commented Jun 6, 2014

Yes, I did restart the server. The part that's not working is this:
ActiveRecord::Base.send(:extend, ActiveRecord::RailsAdminEnum)

It's not actually extending the built-in Rails enum.rb for some reason. By the way, shouldn't extending ActiveRecord::RailsAdminEnum module create #{name}_enum method for you without having to be explicitly defined in your model? It's not overriding the set property either.

@axsuul
Copy link

axsuul commented Jul 13, 2014

Worked for me

@TimSullivan
Copy link

The gist works for display, but when I edit and save, I get an ActiveModel::ForbiddenAttributesError exception.

@PelagicDev
Copy link

I'm getting the following error...
screen shot 2014-07-23 at 11 52 58 am

@Loremaster
Copy link

@jegodwin @TimSullivan To fix you problem you need to install rails_admin from master:

gem 'rails_admin', '0.6.2', git: 'git://github.com/sferik/rails_admin.git', branch: 'master', ref: '02ba1dab32d'

This fixes the error ActiveModel::ForbiddenAttributesError error

@sanrodari
Copy link

Thanks for the gist @dmilisic
+1 to the issue

@fstephany
Copy link

@kenchung Same problem here. Display is fine but creating/saving is not.

(edit: Rails 4.1.5 + RailsAdmin 0.6.3, saving triggers ArgumentError in RailsAdmin::MainController#new '1' is not a valid state which makes me think that the gist does not actually overrides enum)

@VarunBatraIT
Copy link

extend Enumerize
enumerize :ssl_tls, in: [ [ 'not_used', '0' ], [ 'ssl', '1' ], [ 'tls', '2' ] ], default: 'not_used'

This works

@gabu
Copy link

gabu commented Aug 27, 2014

Rails 4.1.5 + RailsAdmin 0.6.3
I also have a same problem.

ArgumentError in RailsAdmin::MainController#edit
'2' is not a valid order_status

@gabu
Copy link

gabu commented Aug 27, 2014

@dmilisic Thanks! Your gist helps for me. It's working.

@mulaiko
Copy link

mulaiko commented Sep 11, 2014

Hi @dmilisic,
First of all thanks for your gist, it helped solve my problem, but now im facing another issue related to your fix. could you help me solve this maybe?
search/filter functionality in rails admin doesnt work anymore after adding the gist above.
im getting the following - i have a users table and im search for a user by the name of "user":

ActiveRecord::StatementInvalid in RailsAdmin::Main#index

.rvm/gems/ruby-2.1.1/gems/rails_admin-0.6.2/app/views/rails_admin/main/index.html.haml where line #128 raised:

PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "user"
LINE 1: ...email) ILIKE '%user%') OR (users.access_level IN ('user'))) ...
^
: SELECT "users".* FROM "users" WHERE ((LOWER(users.email) ILIKE '%user%') OR (users.access_level IN ('user'))) ORDER BY users.id desc LIMIT 20 OFFSET 0

Extracted source (around line #128):

%th.other.right.shrink= "..."
%th.last.shrink
%tbody

  • @objects.each do |object|
    %tr{class: "#{@abstract_model.param_key}_row"}
    %td
    = check_box_tag "bulk_ids[]", object.id, false

any pointers?

@dmilisic
Copy link
Author

@mulaiko I just came across the same issue. Seems that rails_admin tries to search enum fields like strings. The workaround could be setting searchable option to false for the enum field. Works for me.

config.model 'User' do
  configure :access_level do
    searchable false
  end
end

@dmilisic
Copy link
Author

@jegodwin sorry for the delay... Are you using rails 4.1?

@Pavel-Guseynov
Copy link

If you have custom config for model with enum in rails_admin initializer, rename it to z_rails_admin or whatever to load rails_admin_active_record_enum.rb first.

It solve "1 is not a valid" staff.

@osiro
Copy link

osiro commented Nov 6, 2014

Well guys, don't know if anyone here still having issues with Rails Admin and Rails 4 Enum, but anyway here's what I've done to work it out without the need of adding config/initializers/rails_admin_active_record_enum.rb to my initializers:

field :role, :enum do
  searchable false
  enum do
    User.roles.map { |k,_| [k.titleize, k] }
  end

  pretty_value do
    bindings[:object].send(:role).titleize
  end

  def form_value
    bindings[:object].role
  end
end

It partially works, I couldn't make enum fields searchable though, it triggers a invalid SQL statement as mentioned above by @mulaiko.

Anyway... has anyone come up with a workaround for this?

@gcstr
Copy link

gcstr commented Nov 27, 2014

It's not a workaround, but just something to prevent the error since Rails Admin can't filter enum fields:

config.model User do
    field :name
    field :email
    field :kind do
      filterable false
    end
  end

It will prevent Rails Admin from filtering on that field.

@Steviehayes
Copy link

Thanks for the Gist, worked for me as well!!!!

@jacek213
Copy link

Is there a fix for enum filtering? I use version 0.6.5 and when I attempt to filter by enum column rails_admin queries for the actual name of the status instead of integer.

@Sacristan
Copy link

I wonder if this will be implemented in Rails admin anytime soon

@mshibuya mshibuya added this to the 0.7 milestone Mar 25, 2015
@mshibuya mshibuya self-assigned this Mar 25, 2015
@almozavr
Copy link

To add localization (default attribute path translation) support, change getter method definition to

define_method("#{ name }_enum") {
  self.class.send(name.to_s.pluralize).to_a.map do |k, v|
    translated = I18n.t(k, scope: [:activerecord, :attributes, self.class.to_s.downcase, name.to_s.pluralize])
    processed_key = translated.include?('translation missing') ? k : translated
    [processed_key, v]
  end
}

@dgobaud
Copy link

dgobaud commented Jun 5, 2015

searching still seems broken even with the monkey patch

PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "hunter" LINE 1: ...".* FROM "orders" WHERE ((orders.shift_window IN ('hunter'))... ^ : SELECT "orders".* FROM "orders" WHERE ((orders.shift_window IN ('hunter')) OR ....

shift_window is an enum

@siegfried
Copy link

@kenchung @fstephany did you get any luck? Same problem here.

@dgobaud
Copy link

dgobaud commented Jul 29, 2015

no :(

@dmilisic
Copy link
Author

@dgobaud you could disble search for that filed (in config/initializers/rails_admin.rb):

config.model 'Order' do
  configure :shift_window do
    queryable false
  end
end

@dgobaud
Copy link

dgobaud commented Jul 29, 2015

@dmilisic thanks that is what I'm currently doing but I would like search to work ideally

@mshibuya
Copy link
Member

Done 🌟

@dgobaud
Copy link

dgobaud commented Aug 15, 2015

awesome thanks!

@dgobaud
Copy link

dgobaud commented Oct 28, 2015

this is still happening in 0.7.0

@dgobaud
Copy link

dgobaud commented Oct 28, 2015

never mind it was the old monkey patch causing the problem. removed it and now search seems to work

baban added a commit to baban/typus that referenced this issue Feb 6, 2017
To get selector's item, Typus uses plualized name's method.
https://github.com/typus/typus/wiki/customization-selectors

But, when Rails4.1 released. Method name confilected
ActiveRecord::Enum's method name.
so, I research other admin framework gems, and I think best way to
implement enum selector.

1. rails_admin
rails_admin select new method name is like "{column name}_enum"
railsadminteam/rails_admin#1993

2. active admin
active admin select add to parameter in "collection" option.
http://stackoverflow.com/questions/23414880/how-to-properly-configure-rails-4-1-enums-in-activeadmin

and, ActiveRecord::Enum have't I18n. so liker a below gems were released
to support this function.

* https://github.com/brainspec/enumerize
* https://github.com/zmbacker/enum_help

so, We should avoid ActieRecord::Enum i18n gem's implement and use
convenient.
I'll follow rails_admin's way.
@taiwoayanleye
Copy link

This is still happening in 1.1.1. Any fix?

@jeremymarc
Copy link

+1

@dotdidi
Copy link

dotdidi commented May 11, 2017

@onlyyouandty I also did experience the error in 1.1.1 but solve it by changing the data type of the enum from integer to string. Hope that helps

@taiwoayanleye
Copy link

@dotdidi Enum can only be integer values. If you change it to string, the values won't get stored when you try to fill the form because enum calls in integer like [0, 1, 2]. Have you tried it?

@dotdidi
Copy link

dotdidi commented May 12, 2017

@onlyyouandty not necesarilty in rails admin

class ReunionRecord

   def graduating_year_enum
      (1950...Date.today.year)
   end

   def class_enum
      ['Regular', 'International', 'Express']

   rails_admin do
      list do

         field :name do
            filterable true
         end

         field :graduating_year do
            filterable true
         end

         field :class do
            filterable true
         end

I put the graduating_year and class as :string and the enum works without any errors

@taiwoayanleye
Copy link

You are actually right, based on rails/rails#12747, enum could be string like you said. I will have to figure out why it is not saving as string type in my own case.

@tinbka
Copy link

tinbka commented Jul 10, 2017

It still doesn't work. Having

class A < ApplicationRecord
  enum status: %w(a b c)
  rails_admin do
    list do
      field :status, :enum do
        enum {%w(a b c)}
        filterable true
      end
    end
  end
  
  def status_enum
    %w(a b c)
  end
end

(substitute %w(a b c) with {a: 0, b: 1, c: 2}, no difference)

/a?model_name=a&utf8=✓&f%5Bstatus%5D%5B56339%5D%5Bv%5D=c

leads to such a query

SELECT  "as".* FROM "as" WHERE ((as.status IN ('c'))) ORDER BY as.id desc LIMIT $3 OFFSET $4  [["LIMIT", 60], ["OFFSET", 0]]

that fails because as.status is an integer field.

Interestingly, enums work as expected in the edit section with no tweaking: select boxes with word keys and numeric values even though they're treated as integer fields.

@tolgap
Copy link

tolgap commented Aug 13, 2018

I'd say filtering on an enum is one of the strongest things you can do. Disabling filtering on an enum or "status" field is the worst thing I can do in my interface.

Is there a known workaround by now for having both edit support and filter support for enums?

@tinbka
Copy link

tinbka commented Aug 13, 2018

@tolgap isn't it fixed yet? I've seen the note in the changelog that it was done in 1.3.0 by #2971

@AlexMcConnell
Copy link

AlexMcConnell commented Aug 24, 2018

My godawful hacky solution for v0.8.1:

rails_admin.rb

RailsAdmin::ApplicationController.class_eval do
  before_action :fix_params

  def fix_params
    <code to change params how you need to make them work right>
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests