I'm trying to use the pg_search gem in my rails application to search through numerous models from one search bar.
I have added the search bar:
<div id="search-bar">
<%= form_tag searches_path, method: :get do %>
<span><%= text_field_tag :query, params[:query] %><%= submit_tag "Search", name: nil %></span>
<% end %>
</div>
The route:
resources :searches
The searches controller index method:
def index
#results = PgSearch.multisearch(:query)
end
And the search index.html.erb:
<ul>
<% #results.each do |result| %>
<li><%= link_to result.searchable.title, result.searchable %></li>
<% end %>
</ul>
Each model that I want to be searchable has something like this in it:
include PgSearch
multisearchable :against => [:content, :author]
And I have an initializer like this:
PgSearch.multisearch_options = {
:using => {
:tsearch => {
:dictionary => "english"
}
}
}
I created a new item to make sure that it was added to the pg_search_documents table and checked the terminal to see that it was.
Yet when I enter a search query, nothing is coming up in the results table?
Here is the terminal output from the search:
Started GET "/searches?utf8=%E2%9C%93&query=Test" for 127.0.0.1 at 2019-01-16 13:16:48 +0000
Processing by SearchesController#index as HTML
Parameters: {"utf8"=>"✓", "query"=>"Test"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ /Users/---/.rvm/gems/ruby-2.5.3/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Group Exists (0.2ms) SELECT 1 AS one FROM "groups" LIMIT $1 [["LIMIT", 1]]
↳ app/controllers/application_controller.rb:34
Category Exists (0.2ms) SELECT 1 AS one FROM "categories" LIMIT $1 [["LIMIT", 1]]
↳ app/controllers/application_controller.rb:37
Rendering searches/index.html.erb within layouts/application
ggPgSearch::Document Load (20.6ms) SELECT "pg_search_documents".* FROM "pg_search_documents" INNER JOIN (SELECT "pg_search_documents"."id" AS pg_search_id, (ts_rank((to_tsvector('english', coalesce("pg_search_documents"."content"::text, ''))), (to_tsquery('english', ''' ' || 'query' || ' ''')), 0)) AS rank FROM "pg_search_documents" WHERE (((to_tsvector('english', coalesce("pg_search_documents"."content"::text, ''))) ## (to_tsquery('english', ''' ' || 'query' || ' '''))))) AS pg_search_ce9b9dd18c5c0023f2116f ON "pg_search_documents"."id" = pg_search_ce9b9dd18c5c0023f2116f.pg_search_id ORDER BY pg_search_ce9b9dd18c5c0023f2116f.rank DESC, "pg_search_documents"."id" ASC
↳ app/views/searches/index.html.erb:7
Rendered searches/index.html.erb within layouts/application (24.2ms)
Group Load (0.3ms) SELECT "groups".* FROM "groups"
↳ app/views/layouts/application.html.erb:59
Category Load (0.2ms) SELECT "categories".* FROM "categories"
↳ app/views/layouts/application.html.erb:72
Completed 200 OK in 114ms (Views: 88.4ms | ActiveRecord: 21.9ms)
The ul tags are present on the page, but no li items, and I am sure that the term I am putting in was within the item I created.
How come it isn't picking up any results? Many thanks
Did you do the following?
$ rails g pg_search:migration:multisearch
$ rake db:migrate
It's required for multisearching. Also existing items may not be added to the document as you already know. You would need to "rebuild" as stated in the docs. When you made a new item for testing, did you save it properly?
Here are the docs I found for the pg gem:
https://github.com/Casecommons/pg_search
Related
I am working in rails 5.
I am working with a database named "meals". Data base "meals" belongs to a database "events". I have the form_for with meals.
<%= form_for(meal) do |f| %>
I want to a create a drop down with information from database "Events" and then use that as an id for "meals". The dropdown is populated with "events" but i cannot get the event to be selected when I submit the form.
I am using the "select" combined with "options_from_collection_for_select".
</div>
<%= f.select :event_id, options_from_collection_for_select((events), "id", "name", "events.id" ), prompt: 'select' %>
</div>
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9RIvNLt92mYqM5P8m6l3t+vFiNwt/ISzr06pD+0xYlPR+eQR9E9FdsehIn TVwl6U/3q0UHCUw3epaUNuwMvfOw==", "meal"=>{"meal_name"=>"meal", "desc"=>"", "meal_type"=>"", "event_id"=>""}, "commit"=>"Create Meal"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
(0.1ms) begin transaction
(0.1ms) rollback transaction
Thank you!
I am using bootstrap and I have a link that redirects to images#show action from home#index. The link is written in haml:
- url = #entry.class.to_s.downcase.singularize
= link_to(send("#{url}_path", #entry), data: { 'type' => #entry.class.to_s.downcase }) do
= yield
So currently, the home#index displays a list of images and when an image is clicked on, the link written above redirects the user to the view for the specific image Ex: images/1. That is to say that #entry represents the image and when clicked redirects to the specific image or (#entry).
I do not want to move away from the homepage (home#index), I just want to display a modal view that will take into account which images ( or #entry) was clicked on. How do I modify this link and add code that will display a bootstrap modal when the above link is clicked on ? What other steps should I follow ? I just need help to the point of displaying the modal.
Here is my trace:
Started GET "/images/3" for ::1 at 2016-09-07 22:28:10 -0400
Processing by ImagesController#show as */*
Parameters: {"id"=>"3"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Image Load (0.3ms) SELECT "images".* FROM "images" WHERE "images"."id" = $1 LIMIT 1 [["id", 3]]
Group Load (0.4ms) SELECT DISTINCT "groups".* FROM "groups" INNER JOIN "group_memberships" ON "groups"."id" = "group_memberships"."group_id" WHERE "group_memberships"."member_id" = $1 AND "group_memberships"."member_type" = $2 AND "group_memberships"."group_type" = $3 [["member_id", 1], ["member_type", "User"], ["group_type", "Group"]]
GroupMembership Load (0.4ms) SELECT "group_memberships".* FROM "group_memberships" WHERE "group_memberships"."member_id" = $1 AND "group_memberships"."member_type" = $2 [["member_id", 3], ["member_type", "Image"]]
GroupMembership Load (0.5ms) SELECT "group_memberships".* FROM "group_memberships" WHERE "group_memberships"."group_type" = $1 AND "group_memberships"."member_type" = $2 AND "group_memberships"."member_id" = $3 AND "group_memberships"."group_id" IN (-1, -1) [["group_type", "Group"], ["member_type", "User"], ["member_id", 1]]
Rendered images/_modal.html.erb (0.0ms)
Rendered images/show.js.erb (1.2ms)
Completed 200 OK in 27ms (Views: 10.0ms | ActiveRecord: 1.9ms)
One option is to use a js template and change your links to use use the remote: true option:
<%- #images.each do |image| -%>
<%= link_to '...', image_path(image) remote: true %>
<%- end -%>
<div id="modals"></div>
Next in the controller the response type can be set to js (probably a good idea to also keep the html option around):
respond_to do |format|
format.js
end
Then in the template that handles the js:
// app/views/images/show.js.erb
$("#modals").html('<%= j render "images/modal", image: #image %>');
$('#modals .modal').modal();
$('#modals .modal').modal('.toggle');
Finally add a partial for the modal and setup any markup needed:
<!-- app/views/images/_modal.html.erb -->
<div class="modal fade">
...
<%= image_tag(image.url, class: "img-responsive") %>
...
</div>
I have a nested association: state_registrations belong to sponsors. When I try to show the sponsor state_registrations in the view using each, I only get the last record and it prints three times (the total number of state_registrations in my table)
sponsors / _form aka edit creates the table:
<%= f.nested_fields_for :state_registrations,
wrapper_tag: :div do |state_registration_fields| %>
<div class="row" >
<div class="col-sm-1 col-md-1"></div>
<div class="col-sm-3 col-md-3">
<%= state_registration_fields.label :state_license, "State" %>
<%= state_registration_fields.select :state_license,
options_for_select(#state_licenses), {}, {class: "state_license
form-control btn-default btn-block", id: "state_license"} %>
</div> ....
Table - i.e., what's being saved, here, three state_registrations were successively created for a single sponsor with id: '2' (They're out of order because I edited them using the console):
#<ActiveRecord::Relation [
#<StateRegistration id: 8, state_license_number: "CA-1", state_license_name: "CTEC",
sponsor_id: 2, created_at: "2016-01-23 23:45:22", updated_at: "2016-01-24 00:41:50", state_license: "California", course_id: nil>,
#<StateRegistration id: 7, state_license_number: "OR-2", state_license_name: "TP",
sponsor_id: 2, created_at: "2016-01-23 22:12:07", updated_at: "2016-01-24 00:42:06", state_license: "Oregon", course_id: nil>,
#<StateRegistration id: 9, state_license_number: "MD-1", state_license_name: "ITP",
sponsor_id: 2, created_at: "2016-01-24 00:31:44", updated_at: "2016-01-24 00:42:19", state_license: "Maryland", course_id: nil>]>
Better stated, state_license California, state_license_name CTEC, state_license_number CA-1, which correspond to the expected view output.
I have three state_registrations: California (id: 8), Oregon (id: 7), and Maryland (id: 9)
Sponsors controller show
def show
#sponsor = Sponsor.find(params[:id])
#sponsor = current_sponsor
#sponsor.state_registrations = StateRegistration
.where('sponsor_id = ?', current_sponsor.id)
.limit(10).order('state_license asc')
....
sponsor.rb
has_many :state_registrations, dependent: :destroy
has_one :state_registration, dependent: :destroy
accepts_nested_attributes_for :state_registrations,
:allow_destroy => true,
:reject_if => lambda { |e| (e[:state_license].blank?) }
def state_registration
super || build_state_registration
end
state_registration.rb
belongs_to :sponsors
show,htl.erb, part of a table:
<tbody>
<% #sponsor.state_registrations.each do |state_license| %>
<%#= raise state_registration.inspect %>
<tr>
<td><%= #sponsor.state_registration.state_license %></td>
<%#= raise #sponsor.state_registration.state_license.inspect %>
<td><%= #sponsor.state_registration.state_license_name %></td>
<td><%= #sponsor.state_registration.state_license_number %></td>
</tr>
<% end %>
</tbody>
I intentionally left the commented out raise:
<%= raise state_registration.inspect %> # returns California, as
expected - because I sorted in asc order on `state_license` in
the controller and its first alphabetically
<%= raise #sponsor.state_registration.state_license.inspect %> #returns
Maryland, the last record in the table (id: 9)
Now, the curious thing I see in the rails server output is LIMIT 1 which suggests it only returning one record, the last one. I don't understand why raise state_registration returns California and raise #sponsor.state_registration.state_license returns Maryland - in the same show.html.erb refresh
What is seen in the browser [ at http://localhost:3000/sponsors/2 ] is three identical lines in the table:
State License Name License Number
Maryland ITP MD-1
Maryland ITP MD-1
Maryland ITP MD-1
Here's the rails server output:
Started GET "/sponsors/2" for ::1 at 2016-01-23 20:51:14 -0600
Processing by SponsorsController#show as HTML
Parameters: {"id"=>"2"}
Sponsor Load (1.4ms) SELECT "sponsors".* FROM "sponsors"
WHERE "sponsors"."id" = $1 ORDER BY "sponsors"."id" ASC LIMIT 1
[["id", 2]]
Sponsor Load (1.8ms) SELECT "sponsors".* FROM "sponsors"
WHERE "sponsors"."id" = $1 LIMIT 1 [["id", 2]]
I'm 'splitting' the log to show that here StateRegistration loads LIMIT 10 per the sponsor controller
StateRegistration Load (0.8ms) SELECT "state_registrations".*
FROM "state_registrations" WHERE (sponsor_id = 2)
ORDER BY state_license asc LIMIT 10
StateRegistration Load (0.4ms) SELECT "state_registrations".*
FROM "state_registrations"
WHERE "state_registrations"."sponsor_id" = $1 [["sponsor_id", 2]]
(0.2ms) BEGIN
(0.1ms) COMMIT
(0.9ms) SELECT COUNT(*) FROM "cpe_events"
WHERE (sponsor_display_name = 'IL - TEST')
AND (class_date >= '2016-01-23')
(0.9ms) SELECT COUNT(*) FROM "cpe_events"
WHERE (sponsor_display_name = 'IL - TEST')
AND (class_date <= '2016-01-23')
CACHE (0.0ms) SELECT "sponsors".* FROM "sponsors"
WHERE "sponsors"."id" = $1 LIMIT 1 [["id", "2"]]
Photo Load (0.6ms) SELECT "photos".* FROM "photos"
WHERE "photos"."sponsor_id" = $1 LIMIT 1 [["sponsor_id", "2"]]
Instructor Load (0.8ms) SELECT "instructors".* FROM "instructors"
WHERE "instructors"."sponsor_id" = $1 [["sponsor_id", 2]]
Instructor Load (0.9ms) SELECT "instructors".* FROM "instructors"
WHERE "instructors"."sponsor_id" = $1 LIMIT 1 [["sponsor_id", 2]]
Photo Load (0.6ms) SELECT "photos".*
FROM "photos" WHERE "photos"."instructor_id" = $1 LIMIT 1
[["instructor_id", "16"]]
CACHE (0.0ms) SELECT "state_registrations".*
FROM "state_registrations" WHERE (sponsor_id = 2)
ORDER BY state_license asc LIMIT 10
However, here it shows LIMIT 1 - I don't know if this is the cause of my problem or not.
StateRegistration Load (0.4ms) SELECT "state_registrations".*
FROM "state_registrations"
WHERE "state_registrations"."sponsor_id" = $1 LIMIT 1
[["sponsor_id", 2]]
(1.3ms) SELECT COUNT(*) FROM "users" INNER JOIN "relationships"
ON "users"."id" = "relationships"."follower_id"
WHERE "relationships"."followed_id" = $1 [["followed_id", 2]]
Rendered shared/_sponsor_stats.html.erb (6.0ms)
CpeEvent Exists (0.5ms) SELECT 1 AS one FROM "cpe_events"
WHERE "cpe_events"."sponsor_id" = $1 LIMIT 1 [["sponsor_id", 2]]
Rendered sponsors/show.html.erb within layouts/application (111.1ms)
Rendered shared/_google_analytics.erb (0.1ms)
Rendered shared/_html5_shim.html.erb (0.1ms)
Rendered layouts/_navigation_top.html.erb (4.6ms)
Rendered layouts/_messages.html.erb (0.3ms)
Rendered shared/_navigation_bottom.html.erb (1.6ms)
Completed 200 OK in 1899ms (Views: 1867.4ms | ActiveRecord: 12.1ms)
Vexing! I've tried a variety of approaches to resolving this. E.g., limit / no limit to the number of records, defining #sponsor.state_registrations in the controller and view, and defining #state_registrations as StateRegistration.where('sponsor_id =?', current_sponsor.id) so I could iterate over #state_registrations rather than #sponsor.state_registrations using each; however, I still get the last record (Maryland) three times.
I sincerely hope its something simple and my inexperience that's preventing me from resolving this. I think I need a good resource for nested forms.
Any help would be appreciated, including pointing me to the appropriate docs. Thanks in advance.
Look closely at your show code:
<tbody>
<% #sponsor.state_registrations.each do |state_license| %>
<%#= raise state_registration.inspect %>
<tr>
<td><%= #sponsor.state_registration.state_license %></td>
<%#= raise #sponsor.state_registration.state_license.inspect %>
<td><%= #sponsor.state_registration.state_license_name %></td>
<td><%= #sponsor.state_registration.state_license_number %></td>
</tr>
<% end %>
</tbody>
The problem here is you're calling state_registration method, which is a has_one association (but the iteration variable is named state_license). Essentially, you're just calling the same has_one association in a loop. Why do you have has_many and has_one association that points to the same foreign key in the first place?
has_many :state_registrations, dependent: :destroy
has_one :state_registration, dependent: :destroy
I have a next button that is working great, but previous button just does not want to play nice. Funny thing is that I've tried to build this a few different ways referencing methods on SO and elsewhere, but previous always goes to the earliest record...
In my submission model:
def previous
self.class.first(:conditions => ["created_at < ?", created_at], :order => "created_at asc")
end
def next
self.class.first(:conditions => ["created_at > ?", created_at], :order => "created_at asc")
end
And in my view:
<% if #submission.previous %>
<%= link_to "previous", contest_submission_path(#contest, #submission.previous),
:class => 'pull-left btn btn-large' %>
<% end %>
<% if #submission.next %>
<%= link_to "next", contest_submission_path(#contest, #submission.next),
:class => 'pull-right btn btn-large' %>
<% end %>
Like I said, next works great, but previous returns to the earliest record. I'm nearing wits end with this one. Anybody have an answer?
EDITED
Logs:
Started GET "/contests/1/submissions/1" for 127.0.0.1 at 2012-11-30 08:08:52 -0800
Processing by SubmissionsController#show as HTML
Parameters: {"contest_id"=>"1", "id"=>"1"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY users.created_at DESC LIMIT 1
Contest Load (0.3ms) SELECT "contests".* FROM "contests" WHERE "contests"."id" = $1 LIMIT 1 [["id", "1"]]
Submission Load (0.2ms) SELECT "submissions".* FROM "submissions" WHERE "submissions"."id" = $1 ORDER BY submissions.created_at ASC LIMIT 1 [["id", "1"]]
CACHE (0.0ms) SELECT "submissions".* FROM "submissions" WHERE "submissions"."id" = $1 ORDER BY submissions.created_at ASC LIMIT 1 [["id", "1"]]
Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."commentable_id" = 1 AND "comments"."commentable_type" = 'Submission' ORDER BY comments.created_at DESC, created_at
Submission Load (0.3ms) SELECT "submissions".* FROM "submissions" WHERE (created_at < '2012-10-08 14:32:40.590930') ORDER BY submissions.created_at ASC, created_at asc LIMIT 1
Submission Load (0.2ms) SELECT "submissions".* FROM "submissions" WHERE (created_at > '2012-10-08 14:32:40.590930') ORDER BY submissions.created_at ASC, created_at asc LIMIT 1
CACHE (0.0ms) SELECT "submissions".* FROM "submissions" WHERE (created_at > '2012-10-08 14:32:40.590930') ORDER BY submissions.created_at ASC, created_at asc LIMIT 1
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY users.created_at DESC LIMIT 1
Image Load (0.2ms) SELECT "images".* FROM "images" WHERE "images"."parent_id" = 2 AND "images"."parent_type" = 'User' LIMIT 1
Rendered submissions/_follow_unfollow.html.erb (0.1ms)
Image Load (0.4ms) SELECT "images".* FROM "images" WHERE "images"."parent_id" = 1 AND "images"."parent_type" = 'Submission' LIMIT 1
Rendered submissions/_hide_comments_form.html.erb (1.9ms)
Rendered comments/_form.html.erb (2.5ms)
Rendered comments/_comment.html.erb (3.5ms)
Rendered submissions/show.html.erb within layouts/application (21.7ms)
Rendered layouts/_stylesheets.html.erb (4.3ms)
CACHE (0.0ms) SELECT "images".* FROM "images" WHERE "images"."parent_id" = 2 AND "images"."parent_type" = 'User' LIMIT 1
Role Load (0.5ms) SELECT "roles".* FROM "roles" INNER JOIN "assignments" ON "roles"."id" = "assignments"."role_id" WHERE "assignments"."user_id" = 2
Rendered layouts/_header.html.erb (4.6ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 105ms (Views: 97.8ms | ActiveRecord: 3.0ms)
Log #2
Started GET "/contests/1/submissions/%23%3CActiveRecord::Relation:0x007fc3b5e50af8%3E" for 127.0.0.1 at 2012-11-30 08:43:15 -0800
Processing by SubmissionsController#show as HTML
Parameters: {"contest_id"=>"1", "id"=>"#<ActiveRecord::Relation:0x007fc3b5e50af8>"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY users.created_at DESC LIMIT 1
Contest Load (0.3ms) SELECT "contests".* FROM "contests" WHERE "contests"."id" = $1 LIMIT 1 [["id", "1"]]
Submission Load (0.3ms) SELECT "submissions".* FROM "submissions" WHERE "submissions"."id" = $1 LIMIT 1 [["id", "#<ActiveRecord::Relation:0x007fc3b5e50af8>"]]
Completed 500 Internal Server Error in 4ms
ActiveRecord::RecordNotFound (Couldn't find Submission with id=# <ActiveRecord::Relation:0x007fc3b5e50af8>):
app/controllers/submissions_controller.rb:89:in `find_submission'
Final Solution:
In submission.rb
default_scope order: 'submissions.created_at DESC'
def previous_sub
self.class.where("created_at > ?", created_at).reorder("created_at asc").first
end
def next_sub
self.class.where("created_at < ?", created_at).reorder("created_at desc").first
end
In view (show):
<% if #submission.previous_sub %>
<%= link_to "previous", contest_submission_path(#contest, #submission.previous_sub),
:class => 'pull-left btn btn-large' %>
<% end %>
<% if #submission.next_sub %>
<%= link_to "next", contest_submission_path(#contest, #submission.next_sub),
:class => 'pull-right btn btn-large' %>
<% end %>
I ended up exchanging the names of the methods, so that the show record order would match the index, which is scoped in DESC order or most recent to earliest.
Your code is correct, but your log shows
SELECT "submissions".* FROM "submissions"
WHERE (created_at < '2012-10-08 14:32:40.590930')
ORDER BY submissions.created_at ASC, created_at asc LIMIT 1
If this is a query that searches for previous, this is where it fails (because it orders the previous dates in ascending order, and takes the first - the earliest). Could it be you forgot to restart the app after making changes (though it should be reloaded automatically in dev mode)?
Or it is possible you have default_scope or some other scope that breaks the conditions. I wonder why there is submissions.created_at ASC, created_at asc - twice? Probably submissions.created_at ASC is a default scope.
I'd suggest you to use new AR query syntax, and perhaps reorder to exclude other ordering scopes:
self.class.where("created_at < ?", created_at).reorder("created_at desc").first
I built a feature in my app to allow users to search for images that would search the image description,member who uploaded it, and image tags but I have this weird issue where if I search for the name 'jason' it breaks, but a name like 'jesse' works just fine.
Here is my controller
def search_results
#tattoos = Tattoo.where("description LIKE ?", "%#{params[:search]}%") | Tattoo.tagged_with("#{params[:search]}", :any => true ) | Member.where("membername LIKE ?", "%#{params[:search]}%").order("created_at DESC").page(params[:page]).per(10)
end
if i search for 'jason' my app breaks, giving me an 'undefined method' error and the console shows a bunch of stuff not shown if I searched for say, 'jesse'. Im not entirely sure how to word that but here is what I mean.
Search - Jason
Started GET "/search_results?utf8=%E2%9C%93&search=jason&commit=search" for 127.0.0.1 at 2012-05-23 20:48:26 -0400
Processing by IndexController#search_results as HTML
Parameters: {"utf8"=>"✓", "search"=>"jason", "commit"=>"search"}
SQL (0.7ms) SHOW TABLES
ActsAsTaggableOn::Tag Load (0.3ms) SELECT `tags`.* FROM `tags` WHERE (name LIKE 'jason')
Tattoo Load (0.2ms) SELECT `tattoos`.* FROM `tattoos` WHERE (description LIKE '%jason%')
Tattoo Load (0.2ms) SELECT `tattoos`.* FROM `tattoos` WHERE (1 = 0)
SQL (0.7ms) SHOW TABLES
SQL (0.5ms) SHOW TABLES
Member Load (0.3ms) SELECT `members`.* FROM `members` WHERE (membername LIKE '%jason%') ORDER BY fullname asc, created_at DESC LIMIT 10 OFFSET 0
Member Load (0.3ms) SELECT `members`.* FROM `members` WHERE `members`.`id` = 7 ORDER BY fullname asc LIMIT 1
ActsAsTaggableOn::Tag Load (0.3ms) SELECT `tags`.* FROM `tags` INNER JOIN `taggings` ON `tags`.id = `taggings`.tag_id WHERE ((`taggings`.taggable_id = 43) AND (`taggings`.taggable_type = 'Tattoo')) AND (taggings.context = 'styles' AND taggings.tagger_id IS NULL)
Rendered shared/_image_roll.html.erb (27.5ms)
Rendered index/search_results.html.erb within layouts/application (29.3ms)
Completed 500 Internal Server Error in 523ms
Processing by ErrorsController#internal_server_error as HTML
Parameters: {"utf8"=>"✓", "search"=>"jason", "commit"=>"search"}
SQL (0.7ms) SHOW TABLES
SQL (0.5ms) SHOW TABLES
Rendered shared/_register.html.erb (483.4ms)
Member Load (0.2ms) SELECT `members`.* FROM `members` WHERE `members`.`id` = 7 ORDER BY fullname asc LIMIT 1
MemberRole Load (0.2ms) SELECT `member_roles`.* FROM `member_roles` WHERE (`member_roles`.member_id = 7) LIMIT 1
SQL (0.6ms) SHOW TABLES
SQL (0.4ms) SELECT COUNT(*) FROM `tattoos` WHERE `tattoos`.`status` = 'pending'
SQL (0.2ms) SELECT COUNT(*) FROM `feedbacks` WHERE `feedbacks`.`approved` = 0
SQL (0.1ms) SELECT COUNT(*) FROM `tattoos` WHERE `tattoos`.`status` = 'reported'
Rendered shared/_navbar.html.erb (87.6ms)
Rendered shared/_login_form.html.erb (2.9ms)
Rendered errors/internal_server_error.html.erb within layouts/application (582.4ms)
Completed 500 Internal Server Error in 587ms (Views: 583.9ms | ActiveRecord: 3.5ms)
ActionView::Template::Error (undefined method `member' for #<Member:0x007f0b0ca077b0>):
1: <ol class="image_roll">
2: <% #tattoos.each do |t| %>
3: <li>
4: <% unless t.member.nil? %>
5:
6: <%= link_to image_tag(t.file.url(:small),:alt=>"#{strip_tags(t.description)}, #{t.style_list}, tattoos"), member_tattoo_path(t.member, t)%>
7: <% else %>
app/views/shared/_image_roll.html.erb:4:in `block in _app_views_shared__image_roll_html_erb__3185787815883689760_69842755443480_3152220748446100192'
app/views/shared/_image_roll.html.erb:2:in `each'
app/views/shared/_image_roll.html.erb:2:in `_app_views_shared__image_roll_html_erb__3185787815883689760_69842755443480_3152220748446100192'
app/views/index/search_results.html.erb:10:in `_app_views_index_search_results_html_erb___3497910042066847338_69842586729040__4333294961394575926'
Search - Jesse:
Started GET "/search_results?utf8=%E2%9C%93&search=jesse&commit=search" for 127.0.0.1 at 2012-05-23 20:48:36 -0400
Processing by IndexController#search_results as HTML
Parameters: {"utf8"=>"✓", "search"=>"jesse", "commit"=>"search"}
ActsAsTaggableOn::Tag Load (0.6ms) SELECT `tags`.* FROM `tags` WHERE (name LIKE 'jesse')
Tattoo Load (0.7ms) SELECT `tattoos`.* FROM `tattoos` WHERE (description LIKE '%jesse%')
Tattoo Load (0.1ms) SELECT `tattoos`.* FROM `tattoos` WHERE (1 = 0)
Member Load (0.5ms) SELECT `members`.* FROM `members` WHERE (membername LIKE '%jesse%') ORDER BY fullname asc, created_at DESC LIMIT 10 OFFSET 0
Rendered shared/_search.html.erb (0.8ms)
ActsAsTaggableOn::Tag Load (0.2ms) SELECT tags.*, taggings.tags_count AS count FROM `tags` JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM `taggings` INNER JOIN tattoos ON tattoos.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Tattoo' AND taggings.context = 'styles') AND (taggings.taggable_id IN(SELECT tattoos.id FROM `tattoos`)) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id ORDER BY count DESC LIMIT 40
Rendered index/_tags_list.html.erb (19.7ms)
Rendered layouts/shared/_right_column_std.html.erb (22.3ms)
Rendered shared/_register.html.erb (5.7ms)
Member Load (0.3ms) SELECT `members`.* FROM `members` WHERE `members`.`id` = 7 ORDER BY fullname asc LIMIT 1
MemberRole Load (0.1ms) SELECT `member_roles`.* FROM `member_roles` WHERE (`member_roles`.member_id = 7) LIMIT 1
SQL (0.2ms) SELECT COUNT(*) FROM `tattoos` WHERE `tattoos`.`status` = 'pending'
SQL (0.1ms) SELECT COUNT(*) FROM `feedbacks` WHERE `feedbacks`.`approved` = 0
SQL (0.1ms) SELECT COUNT(*) FROM `tattoos` WHERE `tattoos`.`status` = 'reported'
Rendered shared/_navbar.html.erb (13.5ms)
Rendered shared/_login_form.html.erb (2.9ms)
Rendered index/search_results.html.erb within layouts/application (54.3ms)
Completed 200 OK in 64ms (Views: 57.9ms | ActiveRecord: 3.0ms)
And the view:
<% #tattoos.each do |t| %>
<% unless t.member.nil? %>
<%= link_to image_tag(t.file.url(:small),:alt=>"#{strip_tags(t.description)}, #{t.style_list}, tattoos"), member_tattoo_path(t.member, t)%>
<% else %>
<%= link_to image_tag(t.file.url(:small),:alt=>"#{strip_tags(t.description)}, #{t.style_list}, tattoos"), tattoo_path(t) %>
<% end %>
<% end %>
The "| vs ||" issue is not your problem. Doing this:
Tattoo.where(...) | Tattoo.tagged_with(...) | Member.where(...)
will result in an array that is the union of the three input results. Switching to ||:
Tattoo.where(...) || Tattoo.tagged_with(...) || Member.where(...)
will just give you Tattoo.where(...) since that query will never be false or nil and the || will short circuit as soon as it has non-falsey result; Tattoo.where(...) might might be empty but empty and falsey are different things.
Your problem is that you're mixing two different things in one array: Tattoo instances from the first two queries and Member instances from the last query. Then your ERB assumes that everything in #tattoos is a Tattoo (or something else that responds to member):
<% #tattoos.each do |t| %>
<% unless t.member.nil? %>
If your Member.where(...) finds anything, then you will have at least one Member instance in #tattoos and there is no Member#member method as the error message indicates:
ActionView::Template::Error (undefined method `member' for #<Member:0x007f0b0ca077b0>):
Stop mixing two different classes in #tattoos and your problem should go away. Or you could rename it to, say, #matches and smarten up your view logic to be able to display both Tattoo and Member instances.
One thing I noticed is that you are using | instead of || in
#tattoos = Tattoo.where("description LIKE ?", "%#{params[:search]}%") | Tattoo.tagged_with("#{params[:search]}", :any => true ) | Member.where("membername LIKE ?", "%#{params[:search]}%").order("created_at DESC").page(params[:page]).per(10)
perhaps that might be part of the issue?
I would also argue that you should move this logic into the model, which should make it easier to test.
# Controller
#search_results = Tattoo.results_for_search(params[:search])
#search_results << Member.results_for_search(params[:search])
# Tattoo Model
def results_for_search(search_term)
results = where("description LIKE ?", search_term).all
results << tagged_with(search_term, :any => true)
end
# Member Model
def results_for_search(search_term)
where("membername LIKE ?", search_term).order("created_at DESC")
end
# Search Results View
<% #search_results.each do |result| %>
<% if result.is_a?(Tattoo) %>
...
<% elsif result.is_a?(Member) %>
...
<% end %>
<% end %>