In ActiveAdmin Select from list of polymorphic items - activeadmin

So I have a list of items you can select multiple from and the list is of to different things (polymorphic) but I'm not sure how to implement this as what I have isn't working.
I've looked but I can't seem to find anything on this, only on how to filter polymorphic associations (not useful at this juncture).
Currently what I have:
f.input :items, multiple: true, as: :select, collection: Section.top_level.all + NavigationItem.all
I'd also like to add that I have found stuff on polymorphic nested form stuff but again, not relevent to what I'm asking for.

Did you try to use select2 for AA ?
form do |f|
f.inputs do
f.input :sections, as: :select2_multiple, :collection => NavigationItem.find_by_sql('select * from navigation_items'}).pluck(:name, :id)
end
f.actions
end
You can use find_by_sql to search through all polymorphic model across main table. Of course you will want to modify the query to use correct models and section levels.

Related

Is it possible to do a Lookup use Kiba

Is it possible to do a "Lookup" with Kiba.
Since it's quite a normal process in a etl.
Could you show a demo if yes, thanks.
Yes, a lookup can be done with Kiba!
For a tutorial, see this live coding session I recorded, I create a lookup transform to lookup extra fields using a given fields by tapping in the MovieDB database.
Leveraging this example, you could for instance implement a simple ActiveRecord lookup using a block transform:
# assuming you have a 'country_iso_2' field in the row above
transform do |row|
country = Country.where(iso_2: row['country_iso_2']).first
row['country_name'] = country.try(:name) || 'Unknown'
row
end
or you could extract a more reusable class transform that you would call like this:
transform ActiveRecordLookup, model: Country,
lookup_on: 'country_iso_2',
fetch_fields: { 'name' => 'country_name' }
transform DefaultValue, 'name' => 'Unknown'
Obviously, if you have the need for large volumes, you will have to implement some improvements (e.g. caching, bulk reading).
Hope this helps!

jQuery, activeadmin: custom filter with ransack. how to alter displayed text in search box

i got activeadmin (1.0.0.pre1) working with rails-jquery-autocomplete (1.0.2) [rails-4 setup].
i am able to auto-complete queries and call a search on them; however, when the search returns and the index form reloads, the search box (in sidebar panel) displays queried string wrapped in ["string"] (square braces and quotes)
e.g. if i search with AWonderfulDay and select an auto-completed element, the form reload results in ["AWonderfulDay"] shown as innerText of input element (search box)
Following is the generated UI element
<input data-autocomplete="/comments/autocomplete_comments" id="q_comments_in" name="q[comments_in]" type="text" value="["SearchString"]" class="ui-autocomplete-input" autocomplete="off">
The search has been implemented using ransack and the filter is:
filter :comments_in, as: :autocomplete, url: '/comments/autocomplete_comments',
label: 'Search Comments', required: false,
wrapper_html: {style: "list-style: none"}
pointed to a trivial:
ransacker :comment,
:formatter => ->(comment) {
data = User.joins(:profile => :comment).where("comments.comment = ?", comment).map(&:id)
data = data.present? ? data: nil
} do |parent|
parent.table[:id]
end
i do know this is because of in predicate (doesn't happen with cont predicate and i have that in another filter working well, e.g. filter :comments_cont will not cause this)
edit 1:
Also, https://github.com/activerecord-hackery/ransack/issues/345 shows a snapshot with same behavior.
This also led me to another question here Custom search with ransacker
i should have done a better job at looking up for them earlier. sorry for that!
edit 2:
here are my model relations:
class User < ActiveRecord::Base
belongs_to :profile, :inverse_of => :users, :touch => true
class Profile < ActiveRecord::Base
has_one :comment, dependent: :destroy
class Comment < ActiveRecord::Base
belongs_to :profile, touch: true
i solved it by correcting my use of ransack.
In models/comment.rb:
scope :search_comment, lambda { |x| ..}
def self.ransackable_scopes(auth_object = nil)
[:search_comment]
end
In admin/profile.rb
filter :search_comment, as: :autocomplete, url: "controller_url",
label: 'Search Comment', required: false,
wrapper_html: {style: 'list-style: none'}

Customize the search portlet in Plone for specific content types

I'm using the search portlet in certain areas of my website, but I'd like to restrict the results to only search for a specific content type: for example only search the news items, or only show Faculty Staff Directory profiles.
I know you can do this after you get to the ##search form through that "filter" list, but is there a way to start with the filter on, so that the "Live Search" results only show the relevant results (i.e. only news items or only profiles).
I suspect you know it already, but just to be sure: You can globally define which types should be allowed to show up in searchresults in the navigations-settings of the controlpanel, and then export and include the relevant parts to your product's GS-profile-propertiestool.xml.
However, if you would like to have some types excluded only in certain sections, you can customize Products.CMFPlone/skins/plone_scripts/livesearch_reply, which already filters the types, to only show "friendly_types" around line 38 (version 4.3.1) and add a condition like this:
Edit:
I removed the solution to check for the absolute_url of the context, because the context is actually the livesearch_reply in this case, not the current section-location. Instead the statement checks now, if the referer is our section:
REQUEST = context.REQUEST
current_location = REQUEST['HTTP_REFERER']
location_to_filter = '/fullpath/relative/to/siteroot/sectionId'
url_to_filter = str(portal_url) + location_to_filter
types_to_filter = ['Event', 'News Item']
if current_location.find(url_to_filter) != -1 or current_location.endswith(url_to_filter):
friendly_types = types_to_filter
else:
friendly_types = ploneUtils.getUserFriendlyTypes()
Yet, this leaves the case open, if the user hits the Return- or Enter-key or the 'Advanced search...'-link, landing on a different result-page than the liveresults have.
Update:
An opportunity to apply the filtering to the ##search-template can be to register a Javascript with the following content:
(function($) {
$(document).ready(function() {
// Let's see, if we are coming from our special section:
if (document.referrer.indexOf('/fullpath/relative/to/siteroot/sectionId') != -1) {
// Yes, we have the button to toggle portal_type-filter:
if ($('#pt_toggle').length>0) {
// If it's checked we uncheck it:
if ($('#pt_toggle').is(':checked')) {
$('#pt_toggle').click();
}
// If for any reason it's not checked, we check and uncheck it,
// which results in NO types to filter, for now:
else {
$('#pt_toggle').click();
$('#pt_toggle').click();
}
// Then we check types we want to filter:
$("input[value='Event']").click();
$("input[value='News Item']").click();
}
}
})
})(jQuery);
Also, the different user-actions result in different, inconsistent behaviours:
Livesearch accepts terms which are not sharp, whereas the ##search-view only accepts sharp terms or requires the user to know, that you can append an asterix for unsharp results.
When hitting the Enter/Return-key in the livesearch-input, the searchterm will be transmitted to the landing-page's (##search) input-element, whilst when clicking on 'Advanced search...' the searchterm gets lost.
Update:
To overcome the sharp results, you can add this to the JS right after the if-statement:
// Get search-term and add an asterix for blurry results:
var searchterm = decodeURI(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURI('SearchableText').replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")) + '*';
// Insert new searchterm in input-text-field:
$('input[name=SearchableText]').val(searchterm);
Update2:
In this related quest, Eric Brehault provides a better solution for passing the asterix during submit: Customize Plone search
Of course you can also customize the target of advanced-search-link in livesearch_reply, respectively in the JS for ##search, yet this link is rather superfluous UI-wise, imho.
Also, if you're still with Archetypes and have more use-cases for pre-filtered searchresults depending on the context, I can recommend to have a look at collective.formcriteria, which allows to define search-criteria via the UI. I love it for it's generic and straightforward plone-ish approach: catalogued indizi and collections. In contradiction to eea.facetednavigation it doesn't break accessibility and can be enhanced progressively with some live-search-js-magic with a little bit of effort, too. Kudos to Ross Patterson here! Simply turn a collection (old-style) into a searchform by changing it's view and it can be displayed as a collection-portlet, as well. And you can decide which criteria the user should be able to change or not (f.e. you hide the type-filter and offer a textsearch-input).
Watch how the query string changes when you use the filter mechanism on the ##search page. You're simply adding/subtracting catalog query criteria.
You may any of those queries in hidden fields in a search form. For example:
<form ...>
....
<input type="hidden" name="portal_type" value="Document" />
</form>
The form on the query string when you use filter is complicated a bit by its record mechanism, which allows for some min/max queries. Simple filters are much easier.

ActiveAdmin won't save has many and belongs to many field

I have 2 models. Category and Post. They are connected using a has_many_and_belongs_to_many relationship. I checked in the rails console and the relationship works.
I created checkboxes in activeadmin to set the post categories using this form field:
f.input :categories, as: :check_boxes, collection: Category.all
The problem is when I try to save it because every other field data (title, body, meta infos etc.) is saved, but the category stays the same even if I unchecked it, or checked another too.
I am using strong parameters like this:
post_params = params.require(:post).permit(:title,:body,:meta_keywords,:meta_description,:excerpt,:image,:categories)
Please give me some suggestions to make active admin save the categories too!
Best Wishes,
Matt
Try this in AA:
controller do
def permitted_params
params.permit post: [:title, :body, :meta_keywords, :meta_description, :excerpt, :image, category_ids: []]
end
end
Put something like this in /app/admin/post.rb:
ActiveAdmin.register Post do
permit_params :title, :body, :meta_keywords, :meta_description, :excerpt, :image, category_ids: [:id]
end
If you are using accepts_nested_attributes_for then it would look like this:
ActiveAdmin.register Post do
permit_params :title, :body, :meta_keywords, :meta_description, :excerpt, :image, categories_attributes: [:id]
end
I've tested, this might works for you and others as well
# This is to show you the form field section
form do |f|
f.inputs "Basic Information" do
f.input :categories, :multiple => true, as: :check_boxes, :collection => Category.all
end
f.actions
end
# This is the place to write the controller and you don't need to add any path in routes.rb
controller do
def update
post = Post.find(params[:id])
post.categories.delete_all
categories = params[:post][:category_ids]
categories.shift
categories.each do |category_id|
post.categories << Category.find(category_id.to_i)
end
redirect_to resource_path(post)
end
end
Remember to permit the attributes if you're using strong parameters as well (see zarazan answer above :D)
References taken from http://rails.hasbrains.org/questions/369

Thinking Sphinx: Multiple indices for single model?

I'm searching in two different modes using Thinking Sphinx:
Full search on a single model for normal search functionality
Full search across all models for autocomplete dropdown functionality
For the sake of this question, let's say I have a Person and a Country model.
When performing regular searches, I want to fetch all people who's name of country name matches the search string. To achieve this, I have added an index on the countries name in the Person index. All well so far.
When searching to populate my autocomplete dropdown, I want to show all countries and all people matching my search string. Here the problem shows up. When doing an Application-Wide search, I now get:
all countries whose name match my search string
all doctors whose name match my search string, and unfortunately...
all doctors who belongs to a country that matches the search string.
The last part makes for some really confusing autocomplete results for the user. Is there any simple way for me to avoid this by using built-in functionality, for example like having two indices on the Person model, and choose which one to use for each kind of search?
I supposed that your models are like the below:
class Person < ActiveRecord::Base
belongs_to :country
define_index
indexes :name
indexes country(:name), :as => country_name
end
end
class Country < ActiveRecord::Base
has_many :people # has_many :persons # depending on your singular/plural case
define_index
indexes :name
end
end
So, you can get the result without having 3(third condition) by executing the query:
ThinkingSphinx.search :conditions => {:name => params[:q]}, :classes => [Person, Country]
But, if you want to create multiple indexes on a model it can be done like the sample below:
class Person < ActiveRecord::Base
belongs_to :country
define_index :my_first_in do
indexes :name
indexes country(:name)
end
define_index :my_second_in do
indexes :name
end
end
sphinx v3 syntax for the answer above:
ThinkingSphinx::Index.define :country, name: "my_first_in", with: :active_record
indexes name
end

Resources