Rails admin JSONB error when using Carrierwave - ruby-on-rails

I have a Product model with a jsonb column :images to store Carrierwave images.
When trying to edit the product from rails admin, I get the following error:
undefined method `url' for #<Array:0x0000560faa6cefe8>):
Any idea of why am I getting this? It's driving me crazy.
Logs:
Rendering vendor/bundle/ruby/2.7.0/gems/rails_admin-2.2.1/app/views/rails_admin/main/index.html.haml within layouts/rails_admin/application
Product Load (2.6ms) SELECT "products".* FROM "products" ORDER BY products.id desc LIMIT $1 OFFSET $2 [["LIMIT", 20], ["OFFSET", 0]]
Category Load (0.6ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 [["id", 70]]
Rendered vendor/bundle/ruby/2.7.0/gems/rails_admin-2.2.1/app/views/rails_admin/main/index.html.haml within layouts/rails_admin/application (41.9ms)
Completed 500 Internal Server Error in 46ms (ActiveRecord: 3.2ms)
ActionView::Template::Error (undefined method `url' for #<Array:0x00007fb37683cda0>):
102: - if #other_left_link ||= other_left && index_path(params.except('set').merge(params[:set].to_i != 1 ? {set: (params[:set].to_i - 1)} : {}))
103: %td.other.left= link_to "...", #other_left_link, class: 'pjax'
104: - properties.map{ |property| property.bind(:object, object) }.each do |property|
105: - value = property.pretty_value
106: %td{class: "#{property.css_class} #{property.type_css_class}", title: strip_tags(value.to_s)}= value
107: - if #other_right_link ||= other_right && index_path(params.merge(set: (params[:set].to_i + 1)))
108: %td.other.right= link_to "...", #other_right_link, class: 'pjax'
Thanks

Related

Rails turbo stream destroy action handling inexistent parameter

The following execution upon hitting a button <%= button_to fa_icon('bomb', class: 'fa-lg'), importattribute, class: 'button alert small', method: :delete %> in Rails 7
Started DELETE "/importattributes/1" for ...
Processing by ImportattributesController#destroy as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "id"=>"1"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 11], ["LIMIT", 1]]
Importattribute Load (0.3ms) SELECT "importattributes".* FROM "importattributes" WHERE "importattributes"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/importattributes_controller.rb:53:in `set_importattribute'
TRANSACTION (0.2ms) BEGIN
↳ app/controllers/importattributes_controller.rb:47:in `destroy'
TRANSACTION (0.2ms) ROLLBACK
is hitting the error
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column importattributes.importattribute_id does not exist
LINE 1: ...importattributes".* FROM "importattributes" WHERE "importatt...
upon
def destroy
authorize #importattribute
#supplierimport = Supplierimport.find(#importattribute.supplierimport_id)
#importattribute.destroy
redirect_to supplierimport_path(#supplierimport), notice: "Import attribute was successfully destroyed."
end
with the standard private Rails method
def set_importattribute
#importattribute = Importattribute.find(params[:id])
end
Why is Rails looking up in PG importattribute_id instead of id ?
This is also occuring in the test suite & I am quite puzzled by it.

How to get results from a pg_search multisearch

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

Rails api - why incorrect ID send null instead of 404?

When I enter an incorrect track_id in url for example : tracks/123456
=> it returns 404 not found as expected !
If I try with incorrect challenge_id which is one of my other model : tracks/1/challenges/12345
=> it return null instead of 404 not found.
The code of both seems to be the same so I can't found the issue.
If you could help me to found why I get null instead of 404, seeing the code below :
routes.rb
resources :tracks do
resources :challenges do
resources :ressources
end
end
challenges_controller.rb
def show
render json: #challenge, include: [:ressources, :challenges_startups]
end
private
def set_challenge
#track = Track.find(params[:track_id])
#challenge = #track.challenges.where(id: params[:id]).first
end
tracks_controller.rb
def show
render json: #track, include: [:challenges]
end
private
def set_track
#track = Track.find(params[:id])
end
rails_server
For challenges => the wrong one
Started GET "/tracks/3/challenges/20/" for 127.0.0.1 at 2017-07-31 12:24:19 +0200
ActiveRecord::SchemaMigration Load (0.5ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ChallengesController#show as */*
Parameters: {"track_id"=>"3", "id"=>"20"}
Track Load (0.4ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
Challenge Load (0.3ms) SELECT "challenges".* FROM "challenges" WHERE "challenges"."track_id" = ? AND "challenges"."id" = ? ORDER BY "challenges"."id" ASC LIMIT ? [["track_id", 3], ["id", 20], ["LIMIT", 1]]
Startup Load (0.4ms) SELECT "startups".* FROM "startups" ORDER BY "startups"."id" ASC LIMIT ? [["LIMIT", 1]]
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Class (0.18ms)
Completed 200 OK in 63ms (Views: 19.3ms | ActiveRecord: 2.6ms)
For tracks
Started GET "/tracks/222" for 127.0.0.1 at 2017-07-31 12:30:37 +0200
Processing by TracksController#show as */*
Parameters: {"id"=>"222"}
Track Load (0.2ms) SELECT "tracks".* FROM "tracks" WHERE "tracks"."id" = ? LIMIT ? [["id", 222], ["LIMIT", 1]]
Startup Load (0.3ms) SELECT "startups".* FROM "startups" ORDER BY "startups"."id" ASC LIMIT ? [["LIMIT", 1]]
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.16ms)
Completed 404 Not Found in 6ms (Views: 4.1ms | ActiveRecord: 0.5ms)
You have defined #challenge like below
#challenge = #track.challenges.where(id: params[:id]).first
where returns nil if there is no record matching the condition. That is why you get null instead of 404 not found.
Whereas find in contrast returns 404 not found if the record doesn't exist.
If you want to get 404 not found, then modify #challenge like below
#challenge = #track.challenges.find(params[:id])

Previous Button Returns to First for Some Reason in Rails 3 Using Nested Routes

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

Strange controller behavior involving where some params break my app

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 %>

Resources