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

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'}

Related

How to show first preserve_default_filters! and after custom filter

I have this in my code:
preserve_default_filters!
filter :oculto,
as: :check_boxes,
collection: [['Oculto', true], ['visible', false]],
label: 'Mostrar'
I want to show default filters first and show after my custom filter, but I don't know how.
I attached a sample of my index page, how it shows it and how I want it
This is not supported out of the box but reading through the code I found https://github.com/activeadmin/activeadmin/blob/1290efa1fc7984badebe774f108d886a1e82624c/lib/active_admin/filters/resource_extension.rb#L93..L97 which led me to replace preserve_default_filters! above with:
config.send(:default_filters).each { |f| filter f }
filter :oculto ...
This takes the default filters and inserts them before yours. It might be interesting to submit a pull request adding this to lib/activeadmin/filters/dsl.rb:
def default_filters
config.send(:default_filters).each { |f| filter f }
end
Then you would be able to register the resource with:
default_filters
filter :oculto ...

In ActiveAdmin Select from list of polymorphic items

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.

Rails 4.1 Nested Attributes and Fields For Getting Unpermitted Parameters and Not Saving

Research: Rails 4.0 beta, fields_for not accepting pluralized model_name in one-to-many association, Rails 4 Nested Attributes with fields_for Don't Save to Database
First, let's get the most common problem out of the way: incorrectly named attributes parameters for strong parameters. Mine is correctly plural.
class AdultsController < ApplicationController
...
def update
authorize #user
respond_to do |format|
if #user.update_attributes(user_params)
format.html { redirect_to unit_adult_path(#unit, #user), notice: "#{#user.full_name} was successfully updated." }
else
format.html { render action: 'edit' }
end
end
end
def user_params
params.require(:adult).permit(:first_name, :last_name, phones_attributes: [])
end
end
And my models are setup correctly
class User < ActiveRecord::Base
has_many :phones, dependent: :destroy
accepts_nested_attributes_for :phones, allow_destroy: true, reject_if: proc { |a| a["number"].blank? }
end
class Phone < ActiveRecord::Base
belongs_to :user, touch: true
end
And the view
# adult/_form.html.haml
= bootstrap_form_for [#unit, #user] do |f|
= f.text_field :first_name, control_col: 'col-md-4'
= f.text_field :last_name, control_col: 'col-md-4'
= f.fields_for :phones do |f_phone|
= f_phone.form_group do
= f_phone.select :kind, options_for_phones, hide_label: true, layout: :default
= f_phone.phone_field :number, hide_label: true, layout: :default
= f_phone.check_box :_destroy, label: 'remove'
But, when I submit the User form to save
Started PATCH "/units/2/adults/1" for 127.0.0.1 at 2014-07-11 15:20:17 -0700
Processing by AdultsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"pDjDVSiEs5qqHLqnbxQMeGWDOUGvhXPPvgyRGmitmps=", "adult"=>{"first_name"=>"Karl", "last_name"=>"Smith", "phones_attributes"=>{"0"=>{"kind"=>"other", "number"=>"888.1212", "_destroy"=>"0", "id"=>"173"}, "1"=>{"kind"=>"mobile", "number"=>"888.1212", "_destroy"=>"0", "id"=>"174"}} }, "commit"=>"Update Adult", "unit_id"=>"2", "id"=>"1"}
Unpermitted parameters: phones_attributes
I don't understand why the nested data is being rejected by the strong parameter evaluation. It looks correct to me.
The one thing I do notice is that the params data for "phones_attributes" value is a HASH not an ARRAY. In the user_params, phones_attributes: [] looks like it expecting an ARRAY. So I changed it to a HASH.
def user_params
params.require(:adult).permit(:first_name, :last_name, phones_attributes: {})
end
But now I get the following error.
Unpermitted parameters: 0, 1
So I tried specifying the field names in the "phones_attributes" array.
def user_params
params.require(:adult).permit(:first_name, :last_name, phones_attributes: [:id, :kind, :number])
end
And I still get.
Unpermitted parameters: phones_attributes
I know I must be missing something small, but I can't find my error.
EDIT: all my nested attributes forms do not work. Not 100% sure when they stopped, but ones that worked previously no longer work and have not been modified.
Figured this out. I was using javascript to copy the phone fields (kind, number) to make a new set of inputs available for entry. The script was adding non numeric characters to part of the field id, and this was causing rails to ignore all the submitted phone_attributes.
For the next person that comes along...
When fields_for renders out the fields, it will index each input name for uniqueness when the submitted post data is converted to params. In the example below, this number field
<input id="adult_phones_attributes_0_number" name="adult[phones_attributes][0][number]" type="tel" value="7773331111">
will look something like this when converted to params
"phones_attributes"=>{"0"=>{"number"=>"7773331111"}}
The hash key of "0" comes from the index created by fields_for. It's the "[0]" portion of the name.
In versions of rails past, if that nested attributes params hash key was not a number, the k/v pair was just ignored. Well now with strong parameters (I'm guessing the culprit), it will reject the entire "phones_attributes" hash.
My script was copying the input field, doing a regex on the html to change the "[0]" index to a random number. But sometimes it would replace it will non-digit characters. And this was causing the problem.

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