ActiveAdmin Globalize create index filters - ruby-on-rails

I'm using Globalize and ActiveAdmin, and I've now installed a gem from a fork of ActiveAdminGlobalize
Everything that is described in the readme is working, but I'd like to add a filter to the Active Admin Index.
So, for the model stuff.rb
class Stuff < ApplicationRecord
translates :name
active_admin_translates :name do
validates_presence_of :name
end
end
And the class in app/admin/stuff.rb
ActiveAdmin.register Stuff do
index do
translation_status
column :name
end
filter :name
end
How do I make the filter :name to work?
Thanks

I'm using the regular ActiveAdmin gem and, after scratching my head for quite some time, found that the following works:
filter :translations_name_contains, as: :string
Of course you can change name with any other attributes you have translated with Globalize
filter :translations_title_contains, as: :string
To tie everything up nicely, I like to customize the label to avoid the default one AA creates:
filter :translations_title_contains, as: :string, label: "Search", placeholder: "Search page title..."
Hope this helps, thanks!

Related

Rails ActiveAdmin modify resource object

I've currently got a user object but to avoid redundancy, I'd like to wrap it into a presenter object called MerchantUser/ProviderUser. However, with ActiveAdmin, I'm a little confused on how to do this. I've tried using before_create to change the user into the corresponding presenters but in index...do, I'm still seeing that user.class is equal to User and not the wrapper classes that I've defined.
I've looked into scoping_collection but unfortunately that only works on collections and not individual objects?
ActiveAdmin.register User, as: "Companies" do # rubocop:disable Metrics/BlockLength
before_create do |user|
if user.merchant?
user = MerchantUser.new(user)
else
user = ProviderUser.new(user)
end
end
actions :all, except: [:destroy]
permit_params :name, :email, contract_attributes: [:id, :flat_rate, :percentage]
filter :role, as: :select
index do # rubocop:disable Metrics/BlockLength
column :name do |user|
user.name <---I want it so I can just do this without the if/else blocks like below.
end
column :role
column :contact_phone
column :email
column :website do |user|
if user.merchant?
user.company.website
else
user.provider.website
end
end
column :flat_rate do |user|
money_without_cents_and_with_symbol(user.contract.flat_rate)
end
column :percentage do |user|
number_to_percentage(user.contract.percentage, precision: 0)
end
actions
end
Have you looked into Active Admin's support for decorators? This page is quite comprehensive. The best way to implement them depends on how your decorator/presenter object is implemented.
Link summary: use decorate_with or look into using this gem for PORO support
Are you sure you want/need a presenter here? You can register the same Rails model multiple times as ActiveAdmin resources with different names and customizations (filters, index page, forms, etc). You can also use Rails STI or just subclass Rails models, perhaps with different Rails default_scope and then register the subclasses.

Rails_Admin lookup in list

I have this model "Schedule" with attributes :id, :augurid, #and so on.
And I have another model "Augur" with attributes :id, :name, :email #and so on.
Now I want to display augur.name in the Schedule page in Rails_Admin, and my code is like following:
config.model "Schedule" do
list do
fields :id, :weekdays, :occupied, :starting, :duration
field :augur do
pretty_value do
augur = Augur.find(:augurid)
augur.name
end
end
end
edit do
fields :id, :augurid, :weekdays, :occupied, :starting, :duration
end
show do
end
end
But this code is not working, I don't know why since I'm new to rails, and I've checked the documentation of rails_admin, and looks like there's no solution to this problem.
Can anyone help me?
And I think the problem is around
augur = Augur.find(:augurid),
because if I change the :augurid to 5, it will display the right augur name. But how do I do that for every record in schedule?
You should just be able to do add object_label_method :name to the rails_admin configuration for the Augur model:
config.model "Augur" do
object_label_method :name
...
end
Is that what you're looking for?
As #JKen13579 mentioned, :object_label_method :name can do it for you. But if you really want to access the "current object" in your rails_admin callbacks, there is a way:
list do
field :augur do
pretty_value do
bindings[:object].name
end
end
end
This will show the name of the augur and only affect the list view.

Do I need to update an attribute in rails? (and how?)

I generated scaffolding for a class: ExpenseReport
One of the attributes was type - which I created a selct for, where two options where possible: Major and Regular.
When submitting the form to create a report, I was pulling this error:
Invalid single-table inheritance type: Regular is not a subclass of ExpenseReport
My assumption was - "Okay, let's just not have an attribute called type, it looks like that may be causing problems." So I created a migration, renaming type to "report type" and raked (see migration and proof of rake below)
Migration
class UpdaeColumnName < ActiveRecord::Migration
def change
rename_column :expense_reports, :type, :report_type
end
end
Proof of Rake
Drews-MacBook-Pro:depot drewwyatt$ rails generate migration UpdaeColumnName
invoke active_record
create db/migrate/20130820215925_updae_column_name.rb
Drews-MacBook-Pro:depot drewwyatt$ rake db:migrate
== UpdaeColumnName: migrating ================================================
-- rename_column(:expense_reports, :type, :report_type)
-> 0.0021s
== UpdaeColumnName: migrated (0.0021s) =======================================
Now, however, it never ever saves my input, and fires validation with every submit - telling me "Report type is not included in the list", is there another attribute name I need to update or something?
Relevant _form.html.erb
<div class="field">
<%= f.label :report_type %><br>
<%= f.select :report_type, ExpenseReport::TYPES,
prompt: "select one" %>
</div>
Model
class ExpenseReport < ActiveRecord::Base
validates :place_of_purchase, :items, :reason, :estimated_cost,
:requestor_name, presence: true
TYPES = [ 'Major', 'Regular' ]
validates :report_type, inclusion: TYPES
SITES = [ '001 (Lubbock)', '002 (Odessa)', '003 (Midland)', '004 (Lubbock)' ]
validates :site, inclusion: SITES
end
The attribute "type" is for single table inheritance, more about can be found here: http://railscasts.com/episodes/394-sti-and-polymorphic-associations or here: http://rails-bestpractices.com/posts/45-use-sti-and-polymorphic-model-for-multiple-uploads
If you stay with your new report_type, you should change your scaffold stuff. Are you on rails 4? If yes, change your private expense_report_params method in your expense_reports_controller.rb
Should be something like that:
def expense_report_params
params.require(:expense_report).permit(:place_of_purchase, :items, :reason, :estimated_cost, :requestor_name, :other_attributes, :type)
end
Change it to:
def expense_report_params
params.require(:expense_report).permit(:place_of_purchase, :items, :reason, :estimated_cost, :requestor_name, :other_attributes, :report_type)
end
In rails 4 you always have to permit your params..otherwise it would not work. If you permit a params "type" which does not exist, you´ll get an error..

Rails: Select options

I asked a similar question about select options a while ago but I still can't seem to wrap my head around it. I'm rather new to rails but here's what I'm trying to do
I have a Post table & in it, I have a "post_status" column. I
would like to give each post 3 options:
Draft
Pending
Publish
How would I go about creating these 3 options in Rails? (I was advised not to use booleans for this)
Thank you in advance
Elaborating on #Alexander Kobelev answer, I'd put it all in the model:
class Post < ActiveRecord::Base
STATUS_OPTIONS = {
:draft => 'Draft',
:pending => 'Pending',
:published => 'Published'
}
validates_inclusion_of :post_status, :in => STATUS_OPTIONS.keys
end
in your view:
Post Status: <%= select(:post, :post_status, Post::STATUS_OPTIONS.invert) %>
In this particular instance they look like status flags that could be handled a few ways, but you've asked about select options so here's a solution for that method.
Because you don't specify if you need to keep the values already in the table I've detailed a method that allows you to keep them by converting them to IDs (assuming they are currently strings), if this is not relevant then follow only the bold instructions.
Create a PostStatus resource (model, migrate, controller/view if you need the ability to change them).
Define the relationships
PostStatus
has_many :posts
Post
belongs_to :post_status
Add values to your PostStatus table (if you have a live system with strings in the table you should match the existing post status strings here to allow you to convert the data (detailed below).
Change column name to post_status_id in the Post table, change its type to int. If this isn't live then just redo the migrate with the column as integer. If it is a live system you'll need to convert your data into a new column instead of just changing its type, the below is a suggested method.
add_column :posts, :post_status_id_tmp, :int
Post.reset_column_information # make the new column available to model methods
Post.all.each do |post|
# Assuming you have a string with the option text currently:
post.post_status_id_tmp = PostStatus.find_by_name(post.post_status).id
post.save
end
remove_column :posts, :post_status
rename_column :posts, :post_status_tmp, :post_status_id
In your post form add a selectbox.
<%= form.collection_select :post_status_id, PostStatus.all, :id, :name %>
That should at the least get you started!
You can try something like this:
class Post < ActiveRecord::Base
validates_inclusion_of :status, :in => [:draft, :pending, :publish]
def status
read_attribute(:status).to_sym
end
def status= (value)
write_attribute(:status, value.to_s)
end
end
where status is :string, limit: 20 (it's just for example) in migration
or you can try to use https://github.com/jeffp/enumerated_attribute

Exclude draft articles from Solr index with Sunspot

I have an indexed model called Article and I don't want solr to index unpublished articles.
class Article < ActiveRecord::Base
searchable do
text :title
text :body
end
end
How can I specify that article that is not #published? should not be indexed?
Be sure to index the published status.
class Article < ActiveRecord::Base
searchable do
text :title
text :body
boolean :is_published, :using => :published?
end
end
Then add a filter to your query
Sunspot.search(Article) do |search|
search.with(:is_published, true)
# ...
end
If you want to make sure unpublished articles are never included in the search index, you can do it this way instead:
class Article < ActiveRecord::Base
searchable :if => :published? do
text :title
text :body
end
end
The model will then only be indexed when published.
My approach is less interesting if you also want admins to be able to search for articles, including unpublished ones, however.
Note: calling article.index! will add the instance to the index regardless of the :if => :method param.
A small look into the code base of sunspot_rails reveals a method called maybe_mark_for_auto_indexing which will be added to the models that include solr. You could override that method and set #marked_for_auto_indexing based on your criteria in the specific model. Its monkey patching but can help you solve the problem. The code for ur reference is in lib/sunspot/searchable.rb.

Resources