Setting up pagination with will_paginate properly - ruby-on-rails

I have been trying to setup pagination properly but I am having trouble following any tutorial and getting it to work properly.
What I basically want setup is that when a user chooses the number of companies they want to appear on a page, the following loop with paginate the given number of companies on each page. If the user doesn't choose a specific number of companies/page, there would be a default value that would be set.
If anyone could maybe give me a push in the right direction, that would be much appreciated.
View
<ul class="list-group">
<%= #comps.find_each do |comp| %>
<li class="list-group-item">
<div class="row">
<div class="span12">
<p style="font-size: 1.5em"><strong><%= link_to comp.name, comp %></strong></p>
<hr class="divider">
<div class="row">
<div class="span6">
<p><strong>Primary Field:</strong> <%= comp.primary_field %></p>
<p><strong>Description:</strong> <%= truncate(comp.description, length: 150) { link_to "Read More", comp, :target => "_blank"}%>
</p>
</div>
<div class="span5">
<% if signed_in? %>
<p><% if !(current_user.favorites.include? comp) %>
<%= link_to 'Favorite',
favorite_company_path(comp, type: "favorite"),
class: "btn btn-primary",
method: :put%>
<% else %>
<%= link_to 'Unfavorite',
favorite_company_path(comp, type: "unfavorite"),
class: "btn btn-danger",
method: :put%>
<% end %></p>
<% end %>
<p><strong>Website:</strong> <%= auto_link(comp.website, :html => { :target => '_blank' })%></p>
<p><strong>Location:</strong> <%= comp.address %></p>
</div>
</div>
</div>
</div>
</li>
<% end %>
<%= will_paginate #comps%>
</ul>
Controller (Where the list page is handled)
def filter
if ((params[:field] != "") and (params[:field] != "All Fields") and (params[:field] != nil))
# This will apply the filter
#comps = Company.where(primary_field: params[:field])
else
# This will return all records
#comps = Company.all
end
end
def list
#fields = ##primary_field
filter
#comps = #comps.paginate(:page => params[:page], :per_page => params[:number_of_companies] ||= 5)
end
Model for the list page
class DynamicPages < ActiveRecord::Base
self.per_page = 5
end

Since you are using will_paginate. You could do in this way.
Post.paginate(:page => params[:page], :per_page => params[:number_of_companies] ||= 10)
Here params[:number_of_companies] is the number of companies a user has selected and 10 is the
default page value.
class Post
self.per_page = 10
end
Also, your code snippet <%= #comps.find_each do |comp| %>, should be this <% %> instead of <%= %>

Related

ElasticSearch Range Aggregation no output results with no error

Hello I've got this problem with the rails Elascticsearch range aggregations, it seems right as there's no error output but then again it also doesn't aggregate.
Heres my controller
def results
min_price = params[:min_price] if params[:min_price].present?
max_price = params[:max_price] if params[:max_price].present?
price_ranges = [{to: max_price}, {from: min_price, to: max_price}, {from: min_price}]
#results = Item.search(params[:q], aggs: {item_final_price: {ranges: price_ranges}}, page: params[:page], per_page: 10) if params[:q].present?
end
and my model
class Item < ApplicationRecord
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
# Item.import
searchkick callbacks: :async, highlight: [:item_name]
def search_data
{
item_name: item_name,
item_details: item_details,
item_final_price: item_final_price,
item_av_rating: item_av_rating
}
end
end
and my views
<%= form_tag results_path, method: :get, enforce_utf8: false, id: "q_filter" do %>
<section class="widget widget-categories">
<%= hidden_field_tag :q, params[:q] %>
<h3 class="widget-title">Price Range</h3>
<div class="form-group">
<label>Price Between</label>
<%= number_field_tag :min_price, params[:min_price], class: "form-control form-control-sm", placeholder: "Min Price" %>
</div>
<div class="form-group">
<label>And</label>
<%= number_field_tag :max_price, params[:max_price], class: "form-control form-control-sm", placeholder: "Max Price" %>
</div>
<%= button_tag(type: "submit", name: nil, class: "btn btn-outline-primary btn-sm btn-block") do %>
Filter Search
<% end %>
</section>
<% #results.each do |item| %>
<%= item.item_name %>
<% end %>
Try to target this in your view
#results.response["aggregations"]["item_final_price"]["buckets"]
If you're running in development, can you throw a binding.pry and see what the result keys are? The data should be there if the query returns results.

Rails 5 - Nested attributes in form, params missing or empty

I am trying to create two associated objects from two different models but I am still getting the same error "param is missing or the value is empty: repost" I have tried to figure out why it fails for days but in vain. Any hint?
I have the Model repost
class Repost < ApplicationRecord
has_many :recurrences, inverse_of: :repost
accepts_nested_attributes_for :recurrences
def self.create_repost (twit_id)
twit = Twit.find_by_id(twit_id)
Repost.find_or_create_by(link: twit.link) do |repost|
repost.twit_id = twit.id
repost.content = twit.content
repost.image_url = twit.image_url
repost.content_url = twit.content_url
repost.click = 0
repost.like = 0
repost.retweet = 0
repost.engagement = 0
repost.number_of_publications = repost.publications.count
repost.likes_sum = 0
repost.retweets_sum = 0
repost.engagement_sum = 0
repost.recurrence = repost.recurrences.recurring
end
end
and the model Recurrence
class Recurrence < ApplicationRecord
serialize :recurring, Hash
belongs_to :repost, inverse_of: :recurrences
def self.set(repost_id, frequency)
repost = Repost.find_by_id(repost_id)
Recurrence.create do |recurrence|
recurrence.repost_id = repost.id
recurrence.recurring = frequency
recurrence.start_time = recurrence.created_at
recurrence.end_time = nil
end
end
def recurring=(value)
if RecurringSelect.is_valid_rule?(value)
super(RecurringSelect.dirty_hash_to_rule(value).to_hash)
else
super(nil)
end
end
def rule
rule = IceCube::Rule.from_hash(self.recurring)
rule
end
def schedule
schedule = IceCube::Schedule.new(self.created_at)
schedule.add_recurrence_rule(rule)
schedule
end
end
here is my Repost Controller
class RepostsController < ApplicationController
before_action :find_repost, only: [:show, :edit, :update, :destroy, :get_likes]
def index
#repost = Repost.new
if params[:filter_by]
#reposts = Repost.filter(params[:filter_by], params[:min], params[:max], params[:start_at], params[:end_at])
else
#reposts = Repost.all.order("created_at DESC")
end
end
def show
end
def new
#repost = Repost.new
end
def create
#repost = Repost.create_repost(repost_params)
redirect_to reposts_path
end
def destroy
#repost.destroy
redirect_to reposts_path
end
private
def find_repost
#repost = Repost.find(params[:id])
end
def repost_params
params.require(:repost).permit(:twit_id, recurrences_attributes: [:recurring])
end
end
and here is my view with the form
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-sm-offset-1">
<h1 class="twit-h1">My best Tweets</h1>
<p><%= render "filter_form" %></p>
<p><% #twits.each do |twit| %></p>
<p><%= form_for #repost do |f| %></p>
<%= hidden_field_tag :twit_id , twit.id %>
<div class="twit">
<%= image_tag "#{twit.image_url}", class: "twit-image" %>
<div class="twit-body">
<% if twit.content.present? %>
<h3><%= twit.content %></h3>
<% else %>
<%= "This tweet has no text" %>
<% end %>
<% if twit.content_url.present? %>
<%= link_to "#{twit.content_url}".truncate(40), twit.content_url, class: "twit-link" %>
<% else %>
<%= "This tweet has no link" %>
<% end %>
<%= f.fields_for :recurrences do |r| %>
<h6 style="float: right;"><%= r.select_recurring :recurring %></h6>
<% end %>
<h6>
<i class="fa fa-bullhorn fa" aria-hidden="true"></i> <%= twit.engagement %>
<i class="fa fa-retweet fa" aria-hidden="true"></i> <%= twit.retweet %>
<i class="fa fa-heart fa" aria-hidden="true"></i> <%= twit.like %>
</h6>
<p>Tweeted on <%= (twit.first_date).strftime("%A, %B %d, %Y at %I:%M%p %Z") %></p>
<%= link_to "Delete", twit_path(twit), name: nil, class: "btn btn-danger btn-sm", method: :delete, data: {:confirm => 'Are you sure?'} %>
<%= f.submit "Add to your Reposts library", class: "btn btn-primary btn-sm" %>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
</div>
Update, here is my logs
Started POST "/__better_errors/923b59f8da1318ef/variables" for ::1 at 2017-02-21 15:52:56 +0100
Started POST "/reposts" for ::1 at 2017-02-21 15:54:14 +0100
Processing by RepostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"62pE3le5m99HF10RgQcd70wFHqWQWiRmQQO2ndNHT3gnceRu94Y1ttyBuSExBjr4/cxeVUtgY60GRThxdpFGJg==", "twit_id"=>"1844", "recurring"=>"{\"interval\":1,\"until\":null,\"count\":null,\"validations\":{\"day\":[1],\"hour_of_day\":1,\"minute_of_hour\":0},\"rule_type\":\"IceCube::WeeklyRule\",\"week_start\":0}", "commit"=>"Add to your Reposts library"}
Completed 400 Bad Request in 2ms (ActiveRecord: 0.0ms)
ActionController::ParameterMissing - param is missing or the value is empty: repost:
It seems my error comes from this private method in my Repost controller but I can't understand why?
def repost_params
params.require(:repost).permit(:twit_id, recurrences_attributes: [:recurring])
end
Thank you!

How to filter out certain objects in a table with certain ids? (Rails 4, Postgresql)

before I ask my question, I will provide some context.
I have 3 Models which interact with each other.
Scoreboard has many Teams. Team belongs to Scoreboard.
The following use a through table.
Scoreboard many-to-many with User.(let's call this Scoreboard.followers)
Team many-to-many with User.(Let's call this Team.members)
I have a Team_Members Controllers with the following method:
Team_member#new Method:
def new
#selected = true
#scoreboard = Scoreboard.find(params[:scoreboard_id])
#team = Team.find(params[:team_id])
#team_members = #team.members
#followers = #scoreboard.followers.search(params[:search]).paginate(page: params[:page], per_page: 50)
end
What I'm attempting to do is display all the Scoreboard followers in my new.html.erb view. I can search through them and add members to a Team that is associated to the same Scoreboard.
Here's is the new.html.erb view:
<%= form_tag(new_scoreboard_team_team_member_path, :method => "get", id: "member-search-form", autocomplete: "off") do %>
<div class="row new-member-field">
<div class="col-xs-12 col-sm-6">
<%= text_field_tag :search, params[:search], placeholder: "Filter Members by Name", class:"form-control" %>
</div>
</div>
<% end %>
<% if #followers.any? %>
<% #followers.each do |follower| %>
<div class="row member-follower-div" id="follower_<%=follower.id%>">
<div class="col-xs-10 col-sm-5 member-prof-link">
<%= link_to follower.name, user_path(follower.id) %>
</div>
<div class="col-xs-2 col-sm-1 member-add">
<%= link_to (add_scoreboard_team_team_member_path(#scoreboard,#team, follower)), method: :post, remote: true, :data => {:disable_with => ".."} do %>
<i class="fa fa-plus-square fa-lg" aria-hidden="true"></i>
<% end %>
</div>
</div>
<% end %>
<div class="row">
<div class="col-xs-12 col-sm-6 new-member-pages">
<%= will_paginate #followers %>
</div>
</div>
<% end %>
Okay now for the question. The problem arises in the controller method. The #team.members and #scoreboard.followers both source objects from the Users table. How would I filter out the User objects from the #scoreboard.followers that exist in the #team.members? I don't want to display #followers on my view that are a part of the #team.members collection. Also, as a bonus, I would like to alphabetically order the followers by user.name.
I tried the .where("users.id NOT IN (?)", #team_members.pluck(:id)) but if #team_members collection is null, no results are displayed on the page.
I solved it like so:
def new
#selected = true
#scoreboard = Scoreboard.find(params[:scoreboard_id])
#team = Team.find(params[:team_id])
#team_members = #team.members
if (#team_members.any?)
#wonderful_humans = #scoreboard.favourited_by.where("users.id NOT IN (?)", #team_members.pluck(:id)).search(params[:search]).sort_by{ |a| a.name.downcase }
else
#wonderful_humans = #scoreboard.favourited_by.search(params[:search]).sort_by{ |a| a.name.downcase }
end
#followers = #wonderful_humans.paginate(page: params[:page], per_page: 50)
end

rails 4 passing a value to the controller

I have some radio buttons in show.erb.html and i want to pass the value of the selected one to the controller using a submit button or link_to
here is show.html.erb
<ol>
<% for poll_answer in #poll_question.poll_answers %>
<li>
<%= radio_button_tag "poll", poll_answer.content ,true%>
<%= h poll_answer.content %>
</li>
<% end %>
and here is the controller poll_questions_controller.rb
def calc
p = PollAnswer.find_by_content params[:poll]
m= p.counter
if m.nil == true
p.update_attributes counter: 1
else
m = 1+m
p.update_attributes counter: m
end
end
i tried link_to
<% link_to "click here ", controller: :poll_questions, action: :calc, :poll_questions => { :poll=> calc} %>
but it didn't work
Try form_tag helper and set your path
<%= form_tag calc_path do %>
<ol>
<% for poll_answer in #poll_question.poll_answers %>
<li>
<%= radio_button_tag "poll", poll_answer.content ,true%>
<%= h poll_answer.content %>
</li>
<% end %>
</ol>
<%= submit_tag "Submit" %>
<% end %>
In your route.rb file add the following
post 'calc' => 'poll_questions#calc', as: :calc

how to set a return variable in an ajax call in ruby on rails

i am working on a photo sharing app in rails using cloudinary gem.
in my #picasController i have the following relevant actions
def filter
#pica = Pica.find(params[:id])
#new_upload = current_user.picas.first
effect_id = params[:effect_id]
#effect = effect_id.to_sym
respond_to do |format|
format.html { render 'filter' }
format.js
end
end
def share
#pica = Pica.find(params[:id])
#edited_photo_url = params[:edited_photo]
#new_photo_public_id = get_new_public_id(#edited_photo_url)
#pica.update_attributes(photo: #new_photo_public_id, user_id: current_user)
flash.now[:success] = "Saving Photo: Successful"
#new_pica = current_user.picas.first
end
def edit
#pica = Pica.find(params[:id])
#new_upload = current_user.picas.first
end
//views/edit.html.erb
<% render 'shared/filter' %>
//partial
/shared/_filter.html.erb
<h2>Select an effect to apply below:</h2>
<div id="image-display">
<%= cl_image_tag(#new_upload.photo_url(#effect)) %>
<% active_effect = :large %>
</div>
<%= link_to "Remove", #pica, class: "btn btn-warning btn-small", method: :delete,data: { confirm: "Are You sure?" } %><br/>
</div>
<div class="span2 share-photo-btn"><br/><br/><br/><br/><br/><br/>
<%= active_effect %>
<% edited = #new_upload.photo_url(active_effect) %>
<%= edited %>
<%= link_to "Save and Share", {:controller => :picas, :action => :share, :edited_photo => edited, id: #pica.id}, class: "btn btn-info btn-large" %><br/>
</div>
</div><br/>
<div class="effects">
<ul class="thumbnails filters">
<li>
<span class="E_title">Sepia</span>
<% thumb_id = "sepia" %>
<%= link_to image_tag(#new_upload.photo_url(:sepia)), {:controller => :picas, :action => :filter, id: #pica.id, effect_id: thumb_id}, :data => {:remote=> true}, class: "thumbnail", id: "sepia" %>
</li>
<li>
<span class="E_title">Grayscale</span>
<% thumb_id = "grayscale" %>
<%= link_to image_tag(#new_upload.photo_url(:grayscale)), {:controller => :picas, :action => :filter, id: #pica.id, effect_id: thumb_id}, :data => {:remote=> true}, class: "thumbnail", id: "grayscale" %>
</li>
<li>
<span class="E_title">Blackwhite</span>
<% thumb_id = "blackwhite" %>
<%= link_to image_tag(#new_upload.photo_url(:blackwhite)), {:controller => :picas, :action => :filter, id: #pica.id, effect_id: thumb_id}, :data => {:remote=> true}, class: "thumbnail", id: "blackwhite" %>
</li>
//filter.js.erb
<% return_effect = "original" %>
<% case #effect
when :sepia
return_effect = 'sepia'
when :grayscale
return_effect = 'grayscale'
when :blackwhite
return_effect = 'blackwhite'
when :gradient_fade
return_effect = 'gradient_fade'
when :negate
return_effect = 'negate'
when :vignette
return_effect = 'vignette'
else
return_effect
end
%>
//this loads a partial depending on the value of 'return_effect'
$("#image-display").html('<%= escape_javascript(render("#{return_effect}")).html_safe %>')
please my problem is having the active_effect variable in the filter partial set to the correct value whenever a user clicks on an effect. i've tried including it in the partial being loaded when an effect is clicked but it doesent work like this:
when a user clicks on the sepia effect link:
the partial to be loaded with js is this:
//_sepia.html.erb
<%= cl_image_tag(#new_upload.photo_url(:sepia_canvas)) %>
<% active_effect = :sepia_canvas %>
<br/>
but still doesn't work.
all i need is for the value of active_effect variable to be updated whenever a link is clicked.
active_effect is still set on the default :large and doesnt update.
please help i have been cracking my head up for days.
i am ready to provide additional information if needed
For asynchronous tasks, the best practice is not to return any value (if you do, most of the time it returns nothing), instead, if you want to manipulate any data (from async response), pass a callback, handle the data inside the callback.
Don't:
def async_task
do_sth
return response
end
Do:
def async_task(&blk)
do_sth
blk.call(response)
end

Resources