I have my user gender stored as a string male/female (as this is how it is retrieved from Facebook API)
The goal is to render a partial showing users by gender depending on the gender of the logged in user, but I'm having a little trouble setting up a helper
def male
#male = #user.gender.male
end
then my view..
<% #users.male.each do |male| %>
<ul>
<li><%= male.firstname %></li>
<li><%= male.age %></li>
<li><%= male.location %></li>
</ul>
What am I doing wrong, been stuck on this for ages :(
You can use scopes:
class User < ActiveRecord::Base
scope :male, -> { where gender: 'male' }
scope :female, -> { where gender: 'female' }
end
Controller:
def index
#users = User.all
#males = #users.male # or use User.male, but #users might already be filtered
#females = #users.female
end
And in your view:
<%= #males.each do |user| %>
...
<% end %>
Related
I do have a more elaborate index method in my events controller
def index
if params[:q]
params[:q][:combinator] = "and"
params[:q][:groupings] = []
split_geo = params[:q][:address_or_city_or_state_or_country_or_continent_cont_all].split((/(,\s*)+/))
split_geo.map! do |a|
I18n.transliterate a
end
split_geo.each_with_index do |word, index|
params[:q][:groupings][index] = { address_or_city_or_state_or_country_or_continent_cont_all: word }
end
end
#q = Event.ransack(params[:q])
#pagy, #events = pagy(#q.result(distinct: true))
end
In my events index page I have:
<h2>Upcoming Events</h2>
<br>
<%== pagy_bootstrap_nav(#pagy) %>
<br>
<div class="event-list-wrapper">
<% #events.upcoming_events.each do |event| %>
<%= render 'event', event: event %>
<% end %>
</div>
When I remove my upcoming_events scope, the records will display correctly.
In my event.rb model I have:
scope :upcoming_events, -> { where('event_start_date > ?', Time.now).or(where('event_end_date > ?', Date.yesterday)) }
Am I missing something in order to get pagy with work with my event scope?
Guess
it's strange that it certainly occurs when there is no record in the database.
What I tried
I doubted that the cause was actually ajax so I all removed remote:true but it hardly worked.
controller
def create
#sell = current_user.orders.build(sell_params)
#buy = current_user.orders.build(buy_params)
if #sell.save
flash[:success] = 'your order has successfully submitted.'
notify_order(#sell.rate, #sell.amount, #sell.order_type)
#sell.rate.present? ? #sell.update(order_type: 'limit_sell') : #sell.update(order_type: 'market_sell')
fund = Fund.create_with(amount: 0, crypto_address_id: 1)
.find_or_create_by(user_id: current_user.id, kind: #sell.pair.split('_').last)
fund.update(in_use: #sell.rate * #sell.amount) if #sell.order_type == 'limit_sell'
# try to make orders done
market_checker(#sell.pair)
else
if Order.where(order_status: 'done', pair: params[:order][:pair]).present?
#currency_price = Sell.where(trading_status: 'done', currency_id: Currency.find_by_slug(params[:sell][:currency_id]).id)
#currency_price.present? ? #currency_price = #currency_price.last.price : #currency_price = ''
else
flash[:danger] = "Unfortunately, there is no trading right now so that we can't show you the chart"
end
#pair = params[:order][:pair].to_s
render :new
end
if #buy.save
flash[:success] = 'your order has successfully submitted.'
notify_order(#buy.rate, #buy.amount, #buy.order_type)
#buy.rate.present? ? #buy.update(order_type: 'limit_buy') : #buy.update(order_type: 'market_buy')
fund = Fund.create_with(amount: 0, crypto_address_id: 1).find_or_create_by(user_id: current_user.id, kind: #buy.pair.split('_').last)
fund.update(in_use: #buy.rate * #buy.amount) if #buy.order_type == 'limit_buy'
# try to make orders done
market_checker(#buy.pair)
else
if Order.where(order_status: 'done', pair: params[:order][:pair]).present?
#currency_price = Sell.where(trading_status: 'done', currency_id: Currency.find_by_slug(params[:sell][:currency_id]).id)
#currency_price.present? ? #currency_price = #currency_price.last.price : #currency_price = ''
else
flash[:danger] = "Unfortunately, there is no trading right now so that we can't show you the chart"
end
#pair = params[:order][:pair].to_s
render :new
end
end
model
class Order < ApplicationRecord
belongs_to :user
validate :deposited_btc_enough?
validate :insufficient?
validates :amount, format: { with: /\A\d+(?:\.\d{0,8})?\z/ }, numericality: { greater_than: 0.000000009, less_than: 100_000_000 }, presence: true
validate :rate_check
validates :rate, format: { with: /\A\d+(?:\.\d{0,8})?\z/ }, numericality: { greater_than: 0.000000009, less_than: 100_000_000 }, if: :rate_present?
validate :checking_order_type
def rate_present?
rate.present?
end
def checking_order_type
if order_type == 'sell_limit' || order_type == 'buy_limit'
errors.add(:Please, 'specify the rate of your order.') unless rate.present?
end
if order_type == 'sell_market' || order_type == 'buy_market'
errors.add(:You, "can't specify the rate of your order.") if rate.present?
end
end
def deposited_btc_enough?
if rate.present?
if rate.to_d > '0'.to_d && amount > 0
deposited_amount = user.fund.amount if user.fund.amount.present?
amount = rate.to_d * amount.to_s.to_d
if deposited_amount.present?
if coin_to_satoshi(amount).to_i > coin_to_satoshi(deposited_amount).to_i
errors.add(:Your, 'deposited yen is short to order.')
end
else
errors.add(:You, "haven't deposited yen yet or Your transaction hasn't confirmed yet.")
end
else
errors.add(:You, "can't specify negative numbers here.")
end
end
end
def to_param
uuid
end
def insufficient?
if amount.present? && order_type.split('_').last == 'sell'
if CurrencyUser.find_by(user_id: user.id, currency_id: Pair.find_by(name: pair).currency_id).amount < amount
errors.add(:amount, 'of this order is more than your holdings.')
errors[:base] << 'Errors that are related to this order exist.'
end
end
end
def is_number?(string)
true if Float(string)
rescue StandardError
false
end
def rate_check
if rate.present?
errors.add(:You, 'can only specify numbers') unless is_number?(rate)
errors.add(:You, "can't specify the rate as a negative number.") unless '0'.to_d < rate.to_d
end
end
end
form
<%= form_for(#sell,remote:true) do |f| %>
<% if #sell.errors.any? %>
<div id="error_explanation" class="alert alert-danger">
<h2><%= #sell.errors.count %>error(s) exist(s).</h2>
<ul>
<% #sell.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :pair,value:#pair%>
<%= f.hidden_field :order_type,value:"market_sell"%>
<p>amount whatever you want to sell like 100</p>
<div class="input-group">
<%= f.number_field :amount, class: 'form-control form-group',placeholder:"amount"%>
</div>
<%= f.submit 'done', class: "btn btn-large bg-info" %>
<% end %><br>
<%= form_for(#buy,remote:true)do |f| %>
<% if #buy.errors.any? %>
<div id="error_explanation" class="alert alert-danger">
<h2><%= #buy.errors.count %>error(s) exist(s).</h2>
<ul>
<% #buy.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Thanks
Your create method has way too much complexity and I'm assuming you have not written this method with test driven development because you would have broken it down into smaller methods if you had, likely moving more of the logic to the model. I also hope this is not how your code style looks in real life. At first glance, I'm assuming your problem is this:
def create
# why are you creating 2 orders?? Can you change this:
#sell=current_user.orders.build(sell_params)
#buy=current_user.orders.build(buy_params)
#to something more like:
#order = order_from_params
#...omitting rest of this code because it needs a lot of refactoring.
end
private
def order_from_params
#you should probably only deal with 1 order at a time either buy or sell
# you must have a field in orders table to indicate buy or sell, probably int?
if sell_params.present?
#order = current_user.orders.build(sell_params)
else
#order = current_user.orders.build(buy_params)
end
end
Then you'll need to simplify the logic in create method since you only have one model to deal with. You should NOT rely on nor do 2 if #order.save inside the create action since you should again only be creating 1 order at a time. This should get you headed in the right direction. And if you're not doing test driven development, you're gonna have a lot worse problems then what you have already.
I'm a beginner trying out some aspects pertaining to enrollments in my rails app. Users have many enrollments; enrollments belong to a lesson; enrollments have many word_expositions and scrambled_words.
I wrote a helper method in the lessons controller to produce a list of enrolled users, to display in each lesson show page:
helper_method :enrolled_users
def enrolled_users
lesson = Lesson.find(params[:id])
enrollments = lesson.enrollments
enrolled_users = enrollments.map { |enrollment| enrollment.user }
end
I am now trying to implement a completed_expos helper so that I can indicate next to each user whether they have completed the expositional component of my app. What I have is:
helper_method :completed_expos
def completed_expos
lesson = Lesson.find(params[:id])
completed_expos = enrolled_users.map do |user|
current_enrollment = lesson.enrollment_for(user)
all_expos = current_enrollment.word_expositions
all_expos.all? { |expos| expos.completed == true }
end
end
I would like to add a notice next to each listed user regarding whether they completed the expos. So what I tried is:
<% enrolled_users.each do |user| %>
<ul>
<li><%= user.username %></li>
<% if completed_expos.include?(user) %>
completed
<% end %>
</ul>
<% end %>
but the effect is that, although enrolled users are listed, there is no indication as to expo completion in those places where it should list it. How can I go about selecting this subgroup of users?
From what I can get from your code is that your "completed_expos" method will always return an array of Boolean values (true, false) rather than a list of users, so it could never include the user you specify.
I guess what you might want to do was to use select instead of map.
enrolled_users.select do |user|
current_enrollment = lesson.enrollment_for(user)
all_expos = current_enrollment.word_expositions
all_expos.all? { |expos| expos.completed == true }
end
Also, let me say that you don't need to assign the values in each of your methods to a variable with the same name as the method. Eg.
def enrolled_users
lesson = Lesson.find(params[:id])
enrollments = lesson.enrollments
enrolled_users = enrollments.map { |enrollment| enrollment.user }
end
Could be
def enrolled_users
lesson = Lesson.find(params[:id])
enrollments = lesson.enrollments
enrollments.map { |enrollment| enrollment.user }
end
The problem is the helper wasn't returning a user, as to map it into the array:
helper_method :completed_expos
def completed_expos
lesson = Lesson.find(params[:id])
completed_expos = enrolled_users.map do |user|
current_enrollment = lesson.enrollment_for(user)
all_expos = current_enrollment.word_expositions
user if all_expos.all? { |expos| expos.completed == true }
end
end
In my rails app I need to implement a conditional search form .There are two tables named tweets and coordinates , but the output is showing a blank page and I am stuck up with dis.
my coordinates_controller
class CoordinatesController < ApplicationController
def home
end
# def paramas(b)
#
# #b = params[:show]
# return #b
end
#def coor(latitude,longitude)
# #latitude=0
##longitude=0
#end
def query
#a=Coordinates.find("city=?", params[:show])
if(params[:show]= a.city) then
latitude= a.latitude
longitude=a.longitude
end
if(latitude=0 && longitude=0) then
return sql="Select * from tweets where tweet_text LIKE '%text%' AND user_loc LIKE 'params[:show]' order by id desc"
else if (latitude!=0 && longitude!=0)
min_lat = latitude - 1.0
max_lat = latitude + 1.0
min_lng = longitude - 1.0
max_lng = longitude + 1.0
return sql = "Select * from tweets where tweet_text LIKE '%text%' AND ( ((longitude BETWEEN min_lng and max_lng) AND (latitude BETWEEN min_lat and max_lat)) OR (user_loc LIKE 'params[:show]') ) order by id desc"
else
return sql="Select * from tweets where tweet_text LIKE '%text%'"
end
end
end
My Tweets_controller
class TweetsController < ApplicationController
include CoordinatesHelper
def search
render 'tweets/search'
end
def index
# include CoordinatesHelper
sql=query
#tweets=Tweets.paginate_by_sql(sql, :page => #page, :per_page => #per_page )
#render 'tweets/index'
end
end
my view code for the search button
<%=form_tag({controller: 'tweets', action:'index'}, method: "get") do %>
<%=label_tag(:search, "Search for:") %>
<%=text_field_tag(:text) %>
<%=label_tag(:show, "Show for:") %>
<%=text_field_tag(:show) %>
<%= submit_tag( "GO" ) %>
<% end %>
my view code to display the results
<%= will_paginate #tweets %>
<% #tweets.each do |tweets| %>
<ul>
<li><%= tweets.id %></li>
<li><%= tweets.tweet_created_at %></li>
<li><%= tweets.tweet_source %></li>
<li><%= tweets.tweet_text %></li>
<li><%= tweets.user_id %></li>
<li><%= tweets.user_name %></li>
<li><%= tweets.user_sc_name %></li>
<li><%= tweets.user_loc %></li>
<li><%= tweets.user_img %></li>
<li><%= tweets.longitude %></li>
<li><%= tweets.latitude %></li>
<li><%= tweets.place %></li>
<li><%= tweets.country %></li>
</ul>
<% end %>
But for some reasons the output is showing an empty page tried editing several tymes but in vain. Anybody kindly help me wid dis, I am struggling wid dis from a long tym
In your query method, you wrote and finder method, but you have write table name there, not model name, finders works on Model name, write like this :
In your query method replace this :
#a=Coordinates.find("city=?", params[:show])
with this :
#a=Coordinate.find("city=?", params[:show])
because model name, always remain singular, unless you make changes any configuration.
and I think, there is a problem with your params[:show] with this. Please paste your result of 'params[:show]'
Hope it will help. Thanks
I've got two small structural issues that I'm not sure how to handle given my relative newbie-ness with RoR.
First issue: In one of my views, I have code that looks like this:
<ul style="list-style-type: circle">
<li><%= #apples.size %> apples</li>
<li><%= #oranges.size %> oranges</li>
<li><%= #bananas.size %> bananas</li>
<li><%= #grapefruits.size %> grapefruits</li>
</ul>
Is it possible to refactor this so that I only need to iterate once over some list of different kinds of fruit, and have the appropriate <li>'s be automatically generated? Edit: I forgot to add that #apples, #oranges, etc., might be nil. Is there an idiomatic way to handle that?
Second issue: In my controller, I have code that looks like this:
#apples = Apple.find(:all)
#apples.each { |apple| apple.do_stuff(:xyz) }
#bananas = Banana.find(:all)
#bananas.each = { |banana| banana.do_stuff(:xyz) }
# ... &c
As you can see, the same operation is invoked many times in exactly the same way. Is there a way to shorten this to something like [Apple.find(:all), ...].each { |fruit| ... } and have that work instead?
Thanks very much for your help!
I'd do this in a helper
def fruit_size(fruit)
list = #fruits[fruit]
return if list.empty?
content_tag(:li, "#{list.size} #{fruit}")
end
And this in the view:
<% ["apples", "oranges", "bananas", .....].each do |fruit| %>
<%= fruit_size(fruit)
<% end %>
In your controller:
#fruits = {}
["apples", "oranges", "bananas", ......].each do |fruit|
#fruits[fruit] = fruit.classify.constantize.find(:all).each {|record|
record.whatever_here
end
end
It makes sense to store all the items in a hash, #fruits, so that you don't have to use instance_variable_get and stuff.
Perhaps you also want to define that array somewhere, so that you don't have to repeat it in the controller and in the view. Let's pretend that you have a fruit model.
class Fruit < ActiveRecord::Base
FRUITS = ["apples", "oranges", "bananas", ....]
end
Then, use Fruit::FRUITS in the view and controller.
For the first part:
#li = ''
[#apples, #oranges, #bananas, #grapefruit].each{|fruit|
#li << "<li>#{fruit.size}</li>"}
<ul style="list-style-type: circle">
<%=#li%>
</ul>
You can actually do it pretty simply.
In your controller:
def whatever
#fruits = {
:apples => Apple.find(:all).each{ |a| a.do_stuff(:xyz) },
:bananas => Banana.find(:all).each{ |a| a.do_stuff(:xyz) } # ...
}
end
In your view:
<% #fruits.each |k, v| %>
<li><%= v.nil? ? 0 : v.size %> <%= k.to_s %></li>
<% end %>
Although you might want to consider whether do_stuff is something that could be done via a more complex finder, or by named scope.