Saving URL params in a session (rails) - ruby-on-rails

I'm trying to save the url params from ever page, into a session, so if someone fills out a form after navigating away from their landing page it keeps the campaign id. I've managed to make it work page by page, so if they land on the form with params it keeps it, but if they navigate away obviously it doesn't. I currently have:
Controller:
def campaign
if params[:campaign]!= nil
session[:campaign] = params[:campaign]
end
end
def post
rif = Registerinterest.find(:all, :conditions => ["reference = ?", session[:campaign]])
if rif.count == 0
post["Campaign_ID"] = "701D00000001111"
else
post["Campaign_ID"] = rif.first.campaign_id
end
end
It worked when i used params, but not session, so i'm assuming i'm not saving it properly?

You could add a before filter in controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter persist_campaign_session
def persist_campaign_session
session[:campaign] ||= params[:campaign]
end
end
If session[:campaign] is set it will be used, otherwise params[:campaign]will be used. You should implement
the reset of session[:campaign] at a good place.

I put this in my application layout:
- if params[:campaign] != nil || params[:campaign] != ""
- session[:campaign] == params[:campaign]
and then that made the controller work properly:
def post
rif = Registerinterest.find(:all, :conditions => ["reference = ?", session[:campaign]])
if rif.count == 0
post["Campaign_ID"] = "701D00000001111"
else
post["Campaign_ID"] = rif.first.campaign_id
end
end

Related

Unable to convert unpermitted parameters to hash

I've followed multiple stack overflow posts regarding this same issue, but I don't think I have the rails proficiency to know how to apply these fixes to my code.
Been following an old railscast show: http://railscasts.com/episodes/217-multistep-forms
And I'm aware that the issue is something to do with permitting objects/hashes but I just don't understand it all.
The error I'm getting is from this line of code in my controller:
session[:zerch_params].deep_merge!(params[:zerch]) if params[:zerch]
Controller
class ZerchesController < InheritedResources::Base
def index
#zerches = Zerch.all
end
def show
#zerch = Zerch.find(params[:id])
end
def new
session[:zerch_params] ||= {}
#zerch = Zerch.new(session[:zerch_params])
#zerch.current_step = session[:zerch_step]
end
def create
session[:zerch_params].deep_merge!(params[:zerch]) if params[:zerch]
#zerch = Zerch.new(session[:zerch_params])
#zerch.current_step = session[:zerch_step]
if #zerch.valid?
if params[:back_button]
#zerch.previous_step
elsif #zerch.last_step?
#zerch.save if #zerch.all_valid?
else
#zerch.next_step
end
session[:zerch_step] = #zerch.current_step
end
if #zerch.new_record?
render "new"
else
session[:zerch_step] = session[:zerch_params] = nil
flash[:notice] = "zerch complete!"
redirect_to #zerch
end
end
private
def zerch_params
params.require(:zerch).permit(:location, :category, :price)
end
end
So I was able to solve this from the model and in the controller:
I still had
attr_accessor
while also having params in private. I removed this, and also in the controller I changed the line of code from this:
session[:zerch_params].deep_merge!(params[:zerch]) if params[:zerch]
to this:
session[:zerch_params].deep_merge!(params.permit![:zerch]) if params[:zerch]

Rails Ransack - removing element from array

I'm learning how to use ransack, so I have a problem there I'm not sure if it is because the ransack or if it is because the array.
I have a form with 2 text fields (:search and :discipline). So I'm trying do a search using the 1º field parameter AND the 2º field parameter.
The idea is search for all elements that comes from the 1º parameter (field :search, and then remove all the elements that are different from the 2º parameter (field :discipline).
class PagesController < ApplicationController
def home
#rooms = Room.limit(6)
end
def search
if params[:search].present? && params[:search].strip != ""
session[:loc_search] = params[:search]
end
if params[:discipline].present? && params[:discipline].strip != ""
session[:loc_discipline] = params[:discipline]
end
arrResult = Array.new
if session[:loc_search] && session[:loc_search] != ""
#rooms_address = Room.where(active: true).near(session[:loc_search], 5, order: 'distance')
else
#rooms_address = Room.where(active: true).all
end
#search = #rooms_address.ransack(params[:q])
#rooms = #search.result
#arrRooms = #rooms.to_a
if (session[:loc_discipline] && !session[:loc_discipline].empty?)
#rooms.each do |room|
not_available = Room.where(
"(room_type != ?)",
session[:loc_discipline]
)
if not_available.length > 0
#arrRooms.delete(room)
end
end
end
end
end
My #arrRooms is returning NULL after I try do this #arrRooms.delete(room).
I dont know if have a better way to do this, but I'm trying do it like a tutorial that I found.
I assume that you're trying to show all rooms that are not available?
I think the best strategy is to load what you really want, and not loading everything an then deleting the things you don't need. Your code is really hard to read, I suggest you take a little tutorial like this: http://tryruby.org/levels/1/challenges/0, or this: https://www.codeschool.com/courses/ruby-bits
Try extracting code like where(active: true) into a scope like:
class Room < ActiveRecord::Base
scope :active, -> { where(active: true) }
scope :available, -> (discipline) { where.not(room_type: discipline) }
end
In your controller you can then make this:
def index
#rooms = Room.active.available(params[:discipline])
search_param = params[:search].present?
if search_param.present?
#rooms = #rooms.near(session[:loc_search], 5, order: 'distance')
end
#rooms = #rooms.ransack(params[:q]).result(distinct: true)
end
This is what I could guess out of your code.

Query fetches wrong value and NilClass in rails controller

Hi in the following code although the where query inside create method i.e. variable #count_of_fav_texts_present fetches 1 record in the rails console, but in controller the value of #count_of_fav_texts_present is zero and going inside the first if clause.
Also in the internal if clause the query for find_by i.e variable var_fav_text is giving NilClass. Although when I check it in console the value is not Nil, and it has one record.
I am very new to Rails and I am not sure what mistake I am making. Please help.
class NewfavoriteTextsController < ApplicationController
before_action :set_text
before_action :set_favgroup
before_action :authenticate_user!
def create
#count_of_fav_texts_present = Favorite.where(favorited_id: #text_id, user_id: current_user.id).count
if #count_of_fav_texts_present == 0
if Favorite.create(favorited: #text, user: current_user)
if Newfavorite.create(favorite_group_id: #fav_group, newfavorited: #text)
var_fav_text = Favorite.find_by(favorited_id: #text_id, user_id: current_user.id)
cnt_of_var = var_fav_text.counter
var_fav_text.counter = cnt_of_var + 1
var_fav_text.save
else
# do something
end
else
# do something
end
else
# for condition when var is greater than 0
if Newfavorite.create(favorite_group_id: #fav_group, newfavorited: #text)
var_fav_text = Favorite.find_by(favorited_id: #text_id, user_id: current_user.id)
cnt_of_var = var_fav_text.counter
var_fav_text.counter = cnt_of_var + 1
var_fav_text.save
else
# do something
end
end
end
def destroy
# do something
end
private
def set_text
#text = Text.find(params[:text_id] || params[:id])
end
def set_favgroup
#fav_group = params[:fav_group_id]
end
end
Thanks in advance.

How to handle multiple conditions of instance variable assignment

I have the following in my controller that will assign a different collection of results depending on what params are received with an Ajax call. It is messy and i would like to just call a function with all the logic in rather than all this in my index controller
class PublicController < ApplicationController
def index
if params[:literacy_param].present?
#skills = Skill.search(params)
elsif params[:numeracy_param].present?
#skills = Skill.numeracy_default_params
elsif params[:numeracy_number_skills].present?
#skills = Skill.numeracy_number_skills
elsif params[:numeracy_measuring_skills].present?
#skills = Skill.numeracy_measuring_skills
elsif params[:numeracy_data_skills].present?
#skills = Skill.numeracy_data_skills
else
#skills = Skill.default_params
end
end
end
Im just a bit unsure on how to set out my function so that it can read the params that are being sent,
I have come up with this so far
private
def skills(params)
if params[:literacy_param].present?
#skills = Skill.search(params)
elsif params[:numeracy_param].present?
#skills = Skill.numeracy_default_params
elsif params[:numeracy_number_skills].present?
#skills = Skill.numeracy_number_skills
elsif params[:numeracy_measuring_skills].present?
#skills = Skill.numeracy_measuring_skills
elsif params[:numeracy_data_skills].present?
#skills = Skill.numeracy_data_skills
else
#skills = Skill.default_params
end
end
Then in my index action i would do
#skills = skills(params)
would this be an efficient way?
Thanks
You can do this
class PublicController < ApplicationController
def index
skills = ['literacy_param', 'numeracy_param', 'numeracy_number_skills', 'numeracy_measuring_skills', 'numeracy_data_skills']
common_in_params = (skills & params).first
#skills = common_in_params.present? ? (common_in_params.eql?('literacy_param') ? Skill.search(params) : Skill.send(common_in_params)) : Skill.default_params
end
end
You can define skills array in an initializer for resusability
One way of doing it would be this:
def skills(params)
set_of_skills = params.slice(
:numeracy_param,
:numeracy_number_skills,
:numeracy_measuring_skills,
:numeracy_data_skills,
).first
#skills = if params[:literacy_param]
Skill.search(params)
elsif set_of_skills
Skill.public_send(set_of_skills)
else
Skill.default_params
end
end
I would also advise to have this extracted into a lib/ folder, and unit-tested. So that in your controller you could perform the following:
def index
#skills = SkillSearch.new(params).search
end
Two ways I can think of doing this right now:
Wrap the params in a unique key. As in params = { :keyword => :literacy_param }, and then use this unique key to identify the right operation.
In you skill.rb:
def self.filter(params)
if params[:keyword] == :literacy_param
search(params)
elsif available_filters.include?(params[:keyword])
public_send(params[:keyword])
else
default_params
end
end
private
def self.available_filters
%i{numeracy_default_params numeracy_number_skills numeracy_measuring_skills numeracy_data_skills}
end
considering that instead of :numeracy_param, you send :numeracy_default_params in :keyword key. Otherwise you'll have to make another elsif inside filter method.
then in your index method:
def index
#skilles = Skill.filter(params)
end
You create a separate filter class, which is an expandable solution, just in case when you need to go for complex search queries and filtering.
Let's call it SkillSeacrher, inside you app/models/skill_searcher.rb:
class SkillSearcher
attr_reader :keyword
def initialize(keyword)
#keyword = keyword
end
def filter
if keyword == :literacy_param
Skill.search(params)
elsif available_filters.include?(keyword)
Skill.public_send(keyword)
else
Skill.default_params
end
end
private
def self.available_filters
%i{numeracy_default_params numeracy_number_skills numeracy_measuring_skills numeracy_data_skills}
end
end
then in index method:
def index
#skills = SkillSearcher.new(params[:keyword]).filter
end
However, you can do one more change to filter method(depends on your taste):
def filter
if keyword == :literacy_param
Skill.search(params)
else
Skill.public_send(available_filters.include?(keyword) ? keyword : :default_params)
end
end
And, if you have all these methods accepting params as arguments then it'd be much more sleek:
def filter
Skill.public_send(available_filters.include?(keyword) ? keyword : :default_params, params)
end

How to remove current_user from index of all users?

In otherwords, in my app I have an index that displays the number of total users I'd like to exclude the current_user from this list..
I've used the following code to prevent the user.name and user.profile_photo from showing successfully:
<% unless user.hidden_for?(current_user) || user.blocked_for?(current_user) || user == current_user %>
However, it still says Showing 2 users when it only shows the profile photo and name of the other user, it should really only be saying Showing one user and not include me there.
Here is the line of code that ultimately needs the fix:
<h4 class="events_counter">
<%= #users.any? ? "Showing #{pluralize(#users.size, 'people')}" : "No users to show" %>
</h4>
Any help would be awesome!!
Cheers!
Update: (Here's the current relevant index action)
class ProfilesController < ApplicationController
before_filter :authenticate_user!
def index
if params[:search]
terms = params[:search][:terms] || nil
min_age = params[:search][:age_min] || nil
max_age = params[:search][:age_max] || nil
zipcode = params[:search][:zipcode] || nil
distance = params[:search][:distance] || nil
education_id = params[:search][:education_id] || nil
# #ethnicity_id = params[:search][:ethnicity_id] || nil
ethnicity_ids = params[:search][:cat_ids].split('').uniq || nil
gender = params[:search][:gender] || nil
#users = User.active.scoped_by_search(terms, min_age, max_age, education_id, ethnicity_ids, gender)
else
#users = User.active.page params[:page]
end
end
With Rails 4.x,
Assuming that your action name is index where you set the #users instance variable, you could do something like this:
def index
#...
#users = User.active.scoped_by_search(terms, min_age, max_age, education_id, ethnicity_ids, gender).where.not(id: current_user.id)
else
#users = User.active.where.not(id: current_user.id).page params[:page]
#...
end
Here, if you have a current_user then #users will contain all the users except the current_user. Otherwise, #users will have all the users.
Also, you don't require any checks in your view, i.e.,
<% unless user.hidden_for?(current_user) || user.blocked_for?(current_user) || user == current_user %>
is no longer required so you can remove it safely.
Also, #users.size would give the correct count of other users (excluding current_user).
Recommend excluding current_user in the query instead of view. For example in controller:
#users = User.where('id != ?', current_user.id)
However, if you need to keep the current user in the #users array then, use reject to exclude the current user as:
#users.reject { |u| u.id == current_user.id }
I'd suggest building a new array of visible_users somewhere else.
Here is a way to get that array based on your current logic and array.
visible_users = #users.reject{|user| user.hidden_for?(current_user) || user.blocked_for?(current_user) || user == current_user}
Hopefully that helps.

Resources