paperclip image not loading when using "select" in query - ruby-on-rails

In my controller, I get movies with:
movies = Movie.active.includes(:likes).references(:likes).where("likes.user_id = ?", user.id).joins(:collections).active.uniq
I then order and filter them:
#movies = movies.order(query_order).offset(offset).limit(limit + 1)
This output in an PG:Error: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
I quickly found at that you have to select the fields you order by. So I added .select("movies.*, likes.*") to the query.
movies = Movie.select("movies.*, likes.*").active.includes(:likes).references(:likes).where("likes.user_id = ?", user.id).joins(:collections).active.uniq
It works fine except now Paperclip messes up big time. The HTML gets rendered exactly the same as before, but somehow the image doesn't show/process.
=image_tag movie.cover.url(:expanded), :class => "expanded"
When I remove .select("movies.*, likes.*") and .uniq from the query it has duplicate items, but the images work fine.

Because I joined movies with likes it both retrieved the movie.id and the likes.id.
This this paperclip helper couldn't cope with two id's so it randomly picked the likes id.
=image_tag movie.cover.url(:expanded), :class => "expanded"
As a result wrong paths got created: iE. /movies/system/007/movie_with_id_01_image.jpg.
I had to change my select clause, now excluding the likes.id.
.select("movies.*, likes.*")
.select("movies.*, likes.column_a, likes.column_b, ... , likes.column_x")
Now it finally worked again.

Related

How can I use Ransack gem to search a date and another value types in multiple columns?

In my view I wanna search a value in a date column and a string column with the same text_field using Ransack gem.
I've already known how to search multiple strings columns with just one text field, but searching a date column and a string column has been proving to be hard.
I tried something like this in the view:
<%= f.search_field :date_or_name_eq, { :class => "form-control", :placeholder => "Search..." } %>
And this in the controller:
#q = MyModel.ransack(params[:q])
#q.sorts = 'created_at desc' if #q.sorts.empty?
#my_model = #q.result().order(created_at: :desc).page(params[:page]).per(20).distinct
But that, doesn't work. It ignores the name column for searching. It only brings what it find in the date column. And I need something that work for search in theese two columns.
Can someone help me?
For pagination I use the Kaminari gem.
This is absolutely possible with Ransack. Perhaps your date input cannot be parsed (Time.zone.parse is used internally) or that parsed time doesn't actually match anything.
I tried this on my app, where I also use Ransack:
Ruby code:
Client.ransack(name_or_updated_at_eq: '1. Januar 2011').result()
Generated SQL:
SELECT "clients".* FROM "clients" WHERE
("clients"."name" = '1. Januar 2011' OR "clients"."updated_at" = '2011-01-01 00:00:00')
(Note that Rails has no problem parsing the localized date)
The resulting Time instance contains also a time which is missing from the original query input. If the database column doesn't match the same time exactly Ransack returns no match. (With a pure date column this should work, though)
If that is actually the cause, you can use a custom ransacker:
In MyModel add:
ransacker :my_date_column, type: :date do
Arel.sql('date(my_date_column)')
end
Depending on your database backend you might need a different syntax to cast the timestamp into a date. (e.g. try date_trunc('day', my_date_column) for PostgreSQL)
More details on Ransackers: https://github.com/activerecord-hackery/ransack/wiki/using-ransackers

Capybara select for a select-box populated dynamically using a db call

In my index view i have the following select box defined
<%= select_tag('Country', options_for_select(#countries), :class => 'chosen-select') %>
The #countries is populated in the index controller as follows :
#countries = CountryCode.uniq.pluck(:name)
So,as you see a database call is being made to fetch the list of country names to populate the select box.
Now, in my Cucumber steps defintion file i have
Then(/^I should see a select\-box for Countries$/) do
select 'UNITED STATES', :from => 'Country'
end
This is giving me the error Unable to find option "UNITED STATES" (Capybara::ElementNotFound)
But when i check in browser the select box does have that option. Selecting elements using capybara for select-boxes with hardcoded option values is working fine, but in the above case when the options are fetched using a database call the step definition fails. How can i fix this ?
Please Help
Thank You
Is CountryCode an ActiveRecord model? If so, the database is likely empty, which would explain why no values appear in your specs, but development works fine.
You may want to stub out the CountryCode call in the spec's Before hook with something like:
Before do
arel_double = double(:arel)
CountryCode.stub(:uniq).and_return(arel_double)
arel_double.stub(:pluck).with(:name).and_return(['ARUBA', 'UNITED STATES'])
end
Exact syntax will depend on your stub library.

Select helper not showing fields values

I'm trying to build a form with select. I want the select to show the users name and map it the id of their db record. there trouble I'm having is instead of showing the names as the options is how the object id
#<User:0x007fac10de06c0>
this is the code is have used for the select helper
select :task, :assigned_to , #project.team.users{|user| [user.profile.name, user.id]
I think it should be #project.team.users.collect

Rails collection_select modify output

In one of the views (erb) I have the following code
collection_select(:wp_article, :wp_site_id, WpSite.find_by_sql(["SELECT wp_sites.* FROM wp_sites, users_wp_sites, users WHERE users_wp_sites.user_id = users.id and users_wp_sites.wp_site_id = wp_sites.id and username= ?", session[:cur_username]]), :id, :name,
{:prompt => true})
This lists the site names that are accessible by the current user (cur_username) in a drop down list, for example
Google.com
Facebook.com
Twitter.com
Now I need to display the number of times that the user has accessed these sites in the same drop down list, like this:
Google.com (32)
Facebook.com (68)
Twitter.com (21)
How can I modify the query to include the count together with the site name?
(I know how to get the count in a subquery within the same query posted above, but do not know how to pass name of site (:name) and count (the new count I will get in the subquery) to the drop down list as one complete string.)
Managed to solve it in this way:
<%= collection_select(:wp_article, :wp_site_id, WpSite.find_by_sql(["SELECT wp_sites.id, CONCAT(wp_sites.name, ' (', (select count(*) from wp_articles where wp_articles.wp_site_id = wp_sites.id and wp_articles.author = users.username and published = 1), ')') name FROM wp_sites, users_wp_sites, users WHERE users_wp_sites.user_id = users.id and users_wp_sites.wp_site_id = wp_sites.id and username= ?", session[:cur_username]]), :id, :name, {:prompt => true}) %>
In the main SQL query I am using CONCAT (it is a MySQL backend) to append the count to the name and keeping the attribute name "name" (so that it is referenced by symbol :name).

alphabetical pagination in rails

I'm searching a gem for Rails for alphabetical pagination. I wish I could have a list of first letters found in the result (I mean, if there is no row beginning with 'a', I don't want the 'a' to be display on the pagination links). Is this kind of gem already exists?
Thanks in advance!
This wouldn't be too hard to create at all, for example if you had a find, maybe like:
#all_words = Word.select("words.word")
…which returned a result a result set such as a list of words like this:
["alphabet", "boy", "day", "donkey", "ruby", "rails", "iPad"]
…the you could do this:
#all_words.collect {|word| word[0,1]}.uniq.sort
which would return:
["a", "b", "d", "r", "i"]
The .collect {|word| word[0,1]} stores the first letter of each word into a new array whilst uniq filters out the unique letters and sort sorts these alphabetically.
Simply assign this to a variable and you can use it in your view like so:
<ul>
<% #first_letters.each do |letter| %>
<%= content_tag :li, link_to(letter, words_pagination_url(letter), :title => "Pagination by letter: #{letter}") %>
<% end %>
</ul>
Your controller action could then decide what to do with the param from the pagination if one is passed in:
def index
if params[:letter]
#words = Word.by_letter(params[:letter])
else
#words = Word.all
end
end
And then the scope in your model would look something like:
scope :by_letter,
lambda { |letter| {
:conditions => ["words.word LIKE ?", "#{letter}%"]
}}
Your routes require something like:
match "words(/:letter)" => "words#index", :as => words_pagination
I haven't tested this all the way through but it should set you on the right path.
To get a dynamic select from the appropriate table, you can use a dynamic SQL finder.
In this example, we select from a table named 'albums', and fabricate a column 'name' to hold the values. These will be returned in the 'Album' model object. Change any of these names to suit your needs.
Album.find_by_sql("SELECT DISTINCT SUBSTR(name,1,1) AS 'name' FROM albums ORDER BY 1")
Note that you can't use the Album model objects for anything except querying the 'name' field. This is because we've given this object a lobotomy by only populating the 'name' field - there's not even a valid 'id' field associated!
I've created an alphabetical pagination gem here:
https://github.com/lingz/alphabetical_paginate
For anyone still having issues in this domain.

Resources