I am using ActiveAdmin and have an Account model and a User model. Each account will have a has_many relationship with users, and I'd like to be able to list the user names on the account table.
I've seen quite a few SO questions that address the same question and this is how far I've managed to get:
index do
column :id
column :account_status
column :users do |account|
account.users.each do |user|
auto_link user
end
end
column :address do |account|
account.address
end
column :created_at
column :updated_at
actions
end
Note: i've also tried replacing "auto_link user" with "user.name"
This kind of works. It does get the data, but instead of showing attribute values I seem to just get a memory address reference:
I should say here that I am quite new to both Ruby and Rails, so it is likely that I am just missing the point. Considering what I have, is there something I've missed out?
account.users.each will return an array of User objects. That's why you got something like "a memory address reference". To return a list of user.name, you should do something like this:
column :users do |account|
account.users.pluck(:name).join(', ')
end
I use join here to convert an array of names to a string. I'm not sure without join, what will be displayed. You can try it by yourself :)
Related
How would one correctly search multiple models in SunSpot Solr?
Profile model
has_one :match
searchable do
string :country
string :state
string :city
end
Match model
belongs_to :profile
searchable do
string :looking_for_education
integer :age_from
integer :age_to
end
ProfilesController#Index
def index
#search = Sunspot.search Profile, Match do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education]) <= from the 2nd model
end
#profiles = #search.results
end
This fails with:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
Removing the
with(:age).between(params[:age_from]..params[:age_to]) line then it tries to
then it tries to load the
view app/views/educators/educator.html.haml
which does not exist ( im only using
/app/views/profiles/_profile.html.haml
to show profiles
EDIT #1:
What are good opensource projects in ruby on rails that use sunspot and solr in a bit more advanced way to have a look at? Maybe I can find the answer there. Any answer in this direction will also be accepted the bounty if it yields in resulting this issue, thx!
The method you've found for searching multiple models is correct. However, it appears that the meaning of your search is not what you intended. It looks as if you're trying to say:
Give me all Profile records with these country and state values, and whose Match record has this looking_for_education value
Your search, however, says:
Give me all records of type Profile or Match that have all of these country, state and looking_for_education values
Because neither Profile nor Match have all of these fields in their respective searchable blocks, no single record can match the conditions you specify.
If I'm correct about your intended behaviour above, then you need to include the profile's associated match information in the profile's searchable block, like so:
class Profile < ActiveRecord::Base
has_one :match
searchable do
string(:country)
string(:state)
string(:city)
string(:looking_for_education) { match.looking_for_education }
integer(:age_from) { match.age_from }
integer(:age_to) { match.age_to }
end
end
Here, we've told Sunspot to index properties of the profile's match association as if they lived on the profile itself. In the respective blocks, we've told Sunspot how to populate these values when the profile is indexed.
This will allow you to write your search using only the Profile model:
def index
#search = Sunspot.search Profile do
with(:country, params[:country])
with(:state, params[:state])
with(:looking_for_education, params[:looking_for_education])
with(:age).between(params[:age_from]..params[:age_to])
end
#profiles = #search.results
end
This search will return only Profile records, while still reflecting the properties of each profile's match association, because we stored them when the profile was indexed.
Note that this increases complexity when you index your models. If a Match record changes, its associated profile now needs to be reindexed to reflect those changes.
This is what i am doing when i have to search for multiple models
Sunspot.search [Model1, Model2] do
....
end
#moises-zaragoza answered correctly your question but you have more issues than you think with what you want to do.
The first error:
Using a with statement like
with(:age).between(params[:age_from]..params[:age_to])
undefined method `gsub' for nil:NilClass
Is most likely produced because params[:age_from] and/or params[:age_to] are nil. I can't assure it because you haven't shown the stacktrace. You can fix by filter only when they are present:
with(:age).between(params[:age_from]..params[:age_to]) if params[:age_from].present? and params[:age_to].present?
The second error
Related to your views. I am assuming you are rendering a collection or object with one of the rails helper partial object helpers, without specifying the partial (again, without the code this is more of a good guess than anything else):
<%= render #results %>
or
<% #results.each do |result| %>
<%= render result %>
<% end %>
When Rails does not have a partial specified, it guesses the partial name depending on the object type. In this case, if your object is for example of class Educator, which might be a subclass of Profile, Rails will look for the partial 'educators/_educator.html.erb. Make sure you render the proper partial depending on the object type and this will ensure you render what you want.
Here the answer for search different model on matching string using with
searchable(:auto_index => AppConfig.solr.auto_index) do
string :category_name, :stored => true
text :content, :stored => true
text :title
string :company_id, :stored => true
time :published_on
end
search do |q|
if params[:keyword].present?
q.fulltext params[:keyword] do
fields(:deal_data)
end
end
if (ids = params["company_id"]).present?
ids = ids.split(",")
q.with(:company_id,ids) #here company id formate should be ["***","***"]
end
end
I have general field search in ActiveScaffold working. I'm not sure how to do this more complex searching.
I have two tables, Account and User, and I want to search emails and get back a list of matching accounts. The email field is in User, and Account has_many :users.
I am having trouble thinking through how the query should happen. Ideally I'd like to do something like this:
Account.where(email: 'search_term').all
or
User.where(email: 'search_term').includes(:account).all
If you want to search for data from one table and return results from(including) another, just add those foreign columns as virtual columns:
in User controller:
active_scaffold :user do |conf|
conf.search.columns << :email
conf.list.columns << :account
#...
end
That's it, no queries :)
if account column results appears code like <#23423.. it's because Active Scaffold can't tell how to describe that class records, so you tell it how you want in the model:
class Account << ActiveRecord::Base
....
def to_label
"cod: #{account_number}"
end
I have two models, Listing and Invitation, associated with has_and_belongs_to_many. I am looking at invitations through ActiveAdmin and would like to display the names of the associated listings. I attempt this with the following code:
ActiveAdmin.register Invitation do
index do
column("Listings") { |invitation| invitation.listings.each do |listing|
listing.name
end
}
default_actions
end
end
But nothing shows up. How can I get this to work?
I am assuming that you want a single column with all the listings names of the invitation. Please try the following
column 'listing' do |invitation|
invitation.listings.collect(&:name).join(', ')
end
You might want to customize this later on and add a includes(:listings) to increase db retrieval performance.
I'm looking to generate a list of all users signed up as well as a created date and an IP address.
The most important feature is the ability to delete users from this list.
Active_admin seems to be the best choice for this task, but I have found very few results for this scenario. I find it hard to believe because I would assume that this is a common feature.
Any suggestions or links to tutorials?
Thanks in advance!
EDIT:
Ok, so I went and created a user resource through active admin. I.e /app/admin/user.rb
I then went and took some of active_admins demo code and trimmed it down for testing.
ActiveAdmin.register User, :as => "User" do
filter :username
filter :email
filter :created_at
index do
id_column
column :username
column :email
column :created_at
default_actions
end
end
But I get the error:
NoMethodError in Admin::UsersController#index
undefined method `per' for []:ActiveRecord::Relation
Any ideas?
EDIT 2: I just tried:
ActiveAdmin.register User do
def index
#users = User.find(:all)
end
end
and I get the same exact error.
EDIT3:
Found the issue. After some digging, will_paginate gem was causing the conflict!
Everything works now!
With Active Admin, you can display data from every model you have. When for example you have a model user (your front-end users), you just create /app/admin/users.rb and put your stuff in there. Finished.
You can have a look at the code of activeadmin.info on github.
Two questions:
1) How can I make a column in the 'list' for a model consist of data from the record's association? In other words, I have a user model and a user has_many posts. I want to simply have a "post count" column in the list. I tried doing:
field :posts do
formatted_value do
value.count
end
end
but that results in a divide by zero error. I even tried doing:
field :posts do
formatted_value do
bindings[:object].posts.count
end
end
but got the same results.
2) How can I filter the listing to a particular scope? For example, I want to make the users post count be a link that is clickable which will show all posts for the given user.
The best I could figure out how to do this was to do:
# note that I created a method post_count to temporarily solve problem #1
field :post_count do
formatted_value do
bindings[:view].link_to value, "/admin/posts?query=#{bindings[:object].id}"
end
end
Which doesn't work very well. Is there a way to instruct rails-admin to do a .where(:user_id => xxx) on the model?
The other thing I wasn't crazy about was having to manually put in 'admin/posts'.. I was trying to see if I could do rails_admin_list_path(:model_name => "posts"). but that didn't seem to work.
You'd probably get a better response on the rails_admin mailing list - http://groups.google.com/group/rails_admin/
For your first question, this should do the trick:
field :posts, :virtual do
formatted_value do
bindings[:object].posts.count
end
end
For your second question, rails_admin now has a filter system - see the "add filter" dropdown at http://demo.railsadmin.org/admin/players . Tapping into that would be a much better method.
rails_admin_list_path(:model_name => "posts") should work, you might have to include Rails.application.routes.url_helpers or similar.
Try adding this to your rails_admin.rb
RailsAdmin.config {|c| c.label_methods << :field_name}
worked for me