ActiveAdmin (Rails) empty class attribute for custom index table rows - ruby-on-rails

I am using ActiveAdmin to render an index table for a model.
The config looks like this:
ActiveAdmin.register User do
index do
selectable_column
column :username
column "Email" do |u|
raw "<span title='#{u.email}'>#{truncate(u.email, length: 14)}</span>"
end
end
end
The rendered HTML for the "email" TD looks like this:
<td class=""><span title="useremail#example.com">useremail...</span></td>
I have tried passing class: 'foo' before the block and a few things like that but none have worked.
All of the columns that are not being created with the block syntax are getting a class attribute equal to the field name.
How do I set the class for the TD when using a block to render the column?

you have to override build_table_cell method,
you can take needed code here https://gist.github.com/3995962
put it to initializers folder.
now you can use it like
column(:status, :sortable => 'enabled', :class=>'status') do |row|
#some logic
end

Related

Override index columns activeadmin

So I would like to have a shortened table with batch actions.
ActiveAdmin.register User do
batch_action :acitve do |selection|
User.find(selection).each do |user|
user.active! true
end
end
filter :email
index do
column :id
column :first_name
column :last_name
column :email
column :sign_in_count
default_actions
end
end
However batch action box is greyd out. It's understanbale because nothing is selected. However when I use default index settings (no columns specification), the checkbox stays there. How can I have a default checkbox with custom columns?
according to this (Customizing Table Columns part) you need to add
index do
selectable_column #batch actions checkboxes column
column ...
...
end
to render checkboxes

ActiveAdmin show, edit, and delete actions in custom models

I have a rails 3 application which uses the ActiveAdmin gem.
If I do not customizes my models, 3 actions are enabled in each line of my model : show, edit, delete
But if I customizes my model, the actions disappear.
Model not customized showing the actions (users.rb) :
ActiveAdmin.register User, as: 'Users_full' do
menu :parent => 'Users'
end
Custom model not showing actions (companies.rb) :
ActiveAdmin.register Company do
index do
selectable_column
column :name
column :url
end
csv do
column :name
column :url
end
end
Is there a way to get actions in customized models ? I have already tried to add : actions :all, config.batch_actions = true and action_item to my companies.rb file but nothing change.
Add the actions, like:
index do
selectable_column
column :name
column :url
actions
end
You're defining the index page's content, and that content includes the actions-if you omit them, they won't show up.

How to show a serialized Array attribute for a Rails ActiveRecord Model in a form?

We're using the "serialize" feature of ActiveRecord in Rails like this:
class User < ActiveRecord::Base
serialize :favorite_colors, Array
....
end
So we can have
u = User.last
u.favorite_colors = [ 'blue', 'red', 'grey' ]
u.save!
So basically ActiveRecord is serializing the array above and stores it in one database field called favorite_colors.
My question is: How do you allow a user to enter his favorite colors in a form?
Do you use a series of textfields? And once they're entered, how do you show them in a form for him to edit?
This is a question related to Rails Form Helpers for serialized array attribute.
Thanks
If you want multi-select HTML field, try:
= form_for #user do |f|
= f.select :favorite_colors, %w[full colors list], {}, :multiple => true
If you're using simple_form gem, you can present the options as check boxes easily:
= simple_form_for #user do |f|
= f.input :favorite_colors, as: :check_boxes, collection: %w[full colors list]
I have solved this problem by 'flattening' the array in the view and
reconstituting the array in the controller.
Some changes are needed in the model too, see below.
class User < ActiveRecord::Base
serialize :favorite_colors, Array
def self.create_virtual_attributes (*args)
args.each do |method_name|
10.times do |key|
define_method "#{method_name}_#{key}" do
end
define_method "#{method_name}_#{key}=" do
end
end
end
end
create_virtual_attributes :favorite_colors
end
If you don't define methods like the above, Rails would complain about the form element's
names in the view, such as "favorite_colors_0" (see below).
In the view, I dynamically create 10 text fields, favorite_colors_0, favorite_colors_1, etc.
<% 10.times do |key| %>
<%= form.label :favorite_color %>
<%= form.text_field "favorite_colors_#{key}", :value => #user.favorite_colors[key] %>
<% end %>
In the controller, I have to merge the favorite_colors_* text fields into an array BEFORE calling
save or update_attributes:
unless params[:user].select{|k,v| k =~ /^favorite_colors_/}.empty?
params[:user][:favorite_colors] = params[:user].select{|k,v| k =~ /^favorite_colors_/}.values.reject{|v| v.empty?}
params[:user].reject! {|k,v| k=~ /^favorite_colors_/}
end
One thing I'm doing is to hard-code 10, which limits how many elements you can have in the favorite_colors array. In the form, it also outputs 10 text fields. We can change 10 to 100 easily. But we will still have a limit. Your suggestion on how to remove this limit is welcome.
Hope you find this post useful.
To allow access to AR attributes, you have to grant them like this:
class User < ActiveRecord::Base
serialize :favorite_colors, Array
attr_accessible :favorite_colors
....
end

Cannot retrieve lookup values correctly

I've built a lookup table in my Rails application.
It is a table that stores lookup text values for drop-down pickers or possibly check boxes. I want the lookup table to have a view associated so the values can be easily edited. I also may want to share lookup values among multiple models for a single field in the future.
So far I've managed to get it to work for the selection of values, but then displaying the text value again on a show or index view has been problematic.
This is how I built the lookup table
rails g scaffold Lookup field_name lookup_text table_name note
In the edit.html.erb where there is a lookup on a field, I've got code like this, which works and allows me to pick from a list.
<div class="field">
<%= f.label :status %><br />
<%= f.collection_select :status, Lookup.find(:all,:conditions => ["table_name = 'course' and field_name = 'status'"]), :id, :lookup_text, include_blank: true,:prompt => "Status" %>
</div>
That all works fine. When I try to display it back I cannot find the correct syntax. The best I have found is this:
(in the controller)
#status = Lookup.where(:id => #course.status).pluck(:lookup_text)
(in the view)
<p>
<b>Status:</b>
<%= #status %>
</p>
I think I am getting the entire object. It displays like this:
Status: ["Active"]
My questions are:
(1) How do I display the value only?
(2) Is this the best approach?
I've had a look at these and other SO questions, but none are really what I am looking for:
Rails Polymorphic with Lookup Table
Implementing a lookup table in Rails
EDIT
OK this works, but it doesn't look like it is the correct solution. Has anyone got a better way of doing this?
#status = Lookup.where(:id => #course.status).pluck(:lookup_text)[0]
Just another way to show the value is #status = Lookup.find(#course.status).lookup_text
Why not to try use classes for different lookups:
class CourseStatus < ActiveRecord::Base
set_table_name "lookups"
default_scope where("table_name = 'course' and field_name = 'status'")
end
class Course
belongs_to :course_status
end
You then can use:
CourseStatus.all # e.g. to fill select options
Course.first.course_status.lookup_text # => "Active" or smth else
Or without classes:
class Lookup
def self._by_table_and_field(table, field)
['table_name = ? and field_name = ?', table, field]
end
scope :by_table_and_field, lambda { |table, field|
where(Lookup._by_table_and_field(table, field))
}
end
class Course
belongs_to :status, class_name: 'Lookup', conditions: Lookup._by_table_and_field('course', 'status')
end
Lookup.by_table_and_field('course', 'status').all
Course.first.status.lookup_text

Ruby on Rails: Submitting an array in a form

I have a model that has an attribute that is an Array. What's the proper way for me to populate that attribute from a form submission?
I know having a form input with a field whose name includes brackets creates a hash from the input. Should I just be taking that and stepping through it in the controller to massage it into an array?
Example to make it less abstract:
class Article
serialize :links, Array
end
The links variable takes the form of a an array of URLs, i.e. [["http://www.google.com"], ["http://stackoverflow.com"]]
When I use something like the following in my form, it creates a hash:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>
The resultant hash looks like this:
"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}
If I don't include the url in the name of the link, additional values clobber each other:
<%= hidden_field_tag "article[links]", :track, :value => url %>
The result looks like this: "links" => "http://stackoverflow.com"
If your html form has input fields with empty square brackets, then they will be turned into an array inside params in the controller.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[track_codes][]" ...>
# will become the Array
params["course"]["track_codes"]
# with an element for each of the input fields with the same name
Added:
Note that the rails helpers are not setup to do the array trick auto-magically. So you may have to create the name attributes manually. Also, checkboxes have their own issues if using the rails helpers since the checkbox helpers create additional hidden fields to handle the unchecked case.
= simple_form_for #article do |f|
= f.input_field :name, multiple: true
= f.input_field :name, multiple: true
= f.submit
TL;DR version of HTML [] convention:
Array:
<input type="textbox" name="course[track_codes][]", value="a">
<input type="textbox" name="course[track_codes][]", value="b">
<input type="textbox" name="course[track_codes][]", value="c">
Params received:
{ course: { track_codes: ['a', 'b', 'c'] } }
Hash
<input type="textbox" name="course[track_codes][x]", value="a">
<input type="textbox" name="course[track_codes][y]", value="b">
<input type="textbox" name="course[track_codes][z]", value="c">
Params received:
{ course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
I've also found out that if pass your input helper like this you will get an array of courses each one with its own attributes.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[][track_codes]" ...>
# will become the Array
params["course"]
# where you can get the values of all your attributes like this:
params["course"].each do |course|
course["track_codes"]
end
I just set up a solution using jquery taginput:
http://xoxco.com/projects/code/tagsinput/
I wrote a custom simple_form extension
# for use with: http://xoxco.com/projects/code/tagsinput/
class TagInput < SimpleForm::Inputs::Base
def input
#builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(',')))
end
end
A coffeescrpt snippet:
$('input.tag').tagsInput()
And a tweak to my controller, which sadly has to be slightly specific:
#user = User.find(params[:id])
attrs = params[:user]
if #user.some_field.is_a? Array
attrs[:some_field] = attrs[:some_field].split(',')
end
I had a similar issue, but wanted to let the user input a series of comma separated elements as the value for the array.
My migration uses rails new ability (or is it postrges' new ability?) to have an array as the column type
add_column :articles, :links, :string, array: true, default: []
the form can then take this input
<%= text_field_tag "article[links][]", #article.links %>
and it means the controller can operate pretty smoothly as follows
def create
split_links
Article.create(article_params)
end
private
def split_links
params[:article][:links] = params[:article][:links].first.split(",").map(&:strip)
end
params.require(:article).permit(links: [])
Now the user can input as many links as they like, and the form behaves properly on both create and update. And I can still use the strong params.
For those who use simple form, you may consider this solution. Basically need to set up your own input and use it as :array. Then you would need to handle input in your controller level.
#inside lib/utitilies
class ArrayInput < SimpleForm::Inputs::Base
def input
#builder.text_field(attribute_name, input_html_options.merge!({value: object.premium_keyword.join(',')}))
end
end
#inside view/_form
...
= f.input :premium_keyword, as: :array, label: 'Premium Keyword (case insensitive, comma seperated)'
#inside controller
def update
pkw = params[:restaurant][:premium_keyword]
if pkw.present?
pkw = pkw.split(", ")
params[:restaurant][:premium_keyword] = pkw
end
if #restaurant.update_attributes(params[:restaurant])
redirect_to admin_city_restaurants_path, flash: { success: "You have successfully edited a restaurant"}
else
render :edit
end
end
In your case just change :premium_keyword to the your array field
I had some trouble editing the array after implementing this for my new.html.erb, so I'll drop my solution to that problem here:
Edit a model property of type array with Rails form?

Resources