Conditional Text from Helper - ruby-on-rails

I have a set of repeating records that should contain a string that should contain a block of conditional text:
<% if #order.payments.present? %>
<% #order.payments.each do |p| %>
<tr>
<td>Payment</td>
<td>There was a "MY CONDITIONAL TEXT" for <span><%= number_to_currency(p.try(:amount)) %></span></td>
</tr>
<% end %>
<% end %>
So "MY CONDITIONAL TEXT" options would be:
"Partial Payment" when p.amount < #order.value
"Excessive Payment" when p.amount > #order.value
"Payment" when p.amount = #order.value
Is there any way to create a helper method in the OrdersHelper "payment_type" that will help me avoid conditional statements in my views?

yes create a method in helper for that
def method_name(order_value, payment_amount)
if payment_amount < order_value
"Partial Payment"
elsif payment_amount > order_value
"Excessive Payment"
elsif payment_amount = order_value
"Payment"
end
end
now in view
<%= method_name(#order.value, p.amount)%>

Related

How to Make a TODO list item when a database cell matches today's date

I'd like to create a todo list looking for any cell that matches today's date on either agreement, start or due date.
<% #project.where("project_date_agreement + project_date_start + project_date_due > ?", Date.today).each do |tasks_today| %>
<ul>
<li>Item Due Today</li>
</ul>
<% end %>
Any help getting me in right direction would be appreciated.
You want to use OR conditions in your where clause. Properly speaking this would be in your controller.
#projects = Project.where('date_agreement = ? OR date_start = ? or date_due = ?', Date.today, Date.today, Date.today)
In your Project Model you might want to create a field that say's what's due...
def due_because
due_array = []
due_array << 'Agreement date' if date_agreemnt == Date.today
due_array << 'Start date' if date_start == Date.today
due_array << 'Due date' if date_due == Date.today'
due_array.join(', ')
end
Then in your view you would iterate over the #projects
<ul>
<li>Items Due Today</li>
<% #projects.each do |project| %>
<li><%=project.name%> <%=project.due_because%></li>
<% end %>
</ul>
if you asking one row and different column, how about if you combine with table
<% #tasks = #projects.where("date_agreement = ? AND date_start = ? AND date_due = ?",Date.today ,Date.today, Date.today) %>
<table>
<tr>
<ul>
<% #tasks.each do |task| %>
<td>
<li><%= task.check_box :item_due %></li>
</td>
<% end %>
</ul>
</tr>
</table>

rails does create twice when there is no record in a certain model unexpectedly

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.

Ruby on Rails how to use submit button with radio buttons

For my final project I need to create two radio buttons with a submit button that will display my GPA for all my classes and those in my major. I can have them displayed easily but am stuck when I need to use radio buttons to display only one
<h2>Please select which GPA you would like to view:</h2>
<%= form_tag("/trans/transcript", :method => "get") do %>
<table>
<tr>
<th>Major Credits</th>
<th>All Credits</th>
</tr>
<tr>
<td><%= radio_button_tag(:gpa, "Major") %></td>
<td><%= radio_button_tag(:gpa, "All") %> </td>
</tr>
</table>
<%= submit_tag("View GPA") %>
<% end %>
<p> Major credits GPA <%= #transcript.GPA_for_major %>
<p> All credits GPA <%= #transcript.GPA_for_non_major %>
Everything appears fine but I'm not sure how to set up the controller to say if he clicks the major gpa radio button and clicks "View GPA" this <%= #transcript.GPA_for_major %> should display
SHORT ANSWER
Make an instance variable #gpa in TransController's transcript action
In the transcript action, check for params[:gpa]
set #gpa & #transcript to nil if params[:gpa].nil?
set #gpa to params[:gpa] and #transcript accordingly if params[:gpa] is not nil
In the view/trans/transcript.html.erb
If #gpa is nil, display nothing
If #gpa == "Major" show #transcript.GPA_for_major
If #gpa == "All" show #transcript.GPA_for_non_major
LONG ANSWER
Assuming that the controller is trans and the action is transcript, here is what you should do in TransController
class TransController < ApplicationController
def transcript
if params[:gpa].nil?
#transcript = #gpa = nil
else
#gpa = params[:gpa]
#transcript = ... # Find your transcript here
end
end
# ... other actions
# ... other actions
# ... other actions
end
and here is how the trans/transcript.html.erb view should look like -
<h2>Please select which GPA you would like to view:</h2>
<%= form_tag('trans/transcript', :method => "get") do %>
<table>
<tr>
<th>Major Credits</th>
<th>All Credits</th>
</tr>
<tr>
<td>Major<%= radio_button_tag(:gpa, "Major") %></td>
<td>All<%= radio_button_tag(:gpa, "All") %> </td>
</tr>
</table>
<%= submit_tag("View GPA") %>
<% end %>
<% if #gpa == "Major" %>
<%= #transcript.GPA_for_major %>
<% elsif #gpa == "All" %>
<%= #transcript.GPA_for_major %>
<% end %>

Ruby (on Rails) nested if statements with or condition

I was looking for a way to improve this piece of code:
<% if A || B %>
<a></a>
<ul>
<% if A %>
<li>Action A</li>
<% end %>
<li>Action C</li>
<% if B %>
<li>Action B</li>
<% end %>
</ul>
<% end %>
this involves to evaluate A, eventually B and then A again and B again. Any idea on how to improve that code?
P.S.
Order of actions matters.
In your controller:
#action_list = []
if A || B
#action_list << "Action A" if A
#action_list << "Action C"
#action_list << "Action B" if B
end
In your view:
<% if #action_list.count > 0 %>
<a></a>
<ul>
<% #action_list.each do |action| %>
<li><%= action %></li>
<% end %>
</ul>
<% end %>
I'd go with the same approach as msergeant, but stick it in a class like so:
class ActionListItems
def initialize(a = nil, b = nil)
#a = a
#b = b
end
def render?
!!(#a || #b)
end
def each
yield "Action A" if #a
yield "Action C"
yield "Action B" if #b
end
end
action_list_items = ActionListItems.new "a", "b"
puts action_list_items.render?
#=> true
action_list_items.each do |item|
puts item
end
#=> Action A
#=> Action C
#=> Action B

What is the recommended pattern for extend html class in view?

I have following <tr> tag in my table
<% if user.company.nil? %>
<tr class="error">
<% else %>
<tr>
<% end %>
<td><%= user.name %></td>
</tr>
I would like to add another if statement
<% if user.disabled? %>
<tr class="disabled">
<% end %>
So when two of this statements are true I would like to receive:
<tr class="error disabled">
I know I should move that to helper but how to write good case statment for extending class depends of this statements?
def tr_classes(user)
classes = []
classes << "error" if user.company.nil?
classes << "disabled" if user.disabled?
if classes.any?
" class=\"#{classes.join(" ")}\""
end
end
<tr<%= tr_classes(user) %>>
<td><%= user.name %></td>
</tr>
But the good style is:
def tr_classes(user)
classes = []
classes << "error" if user.company.nil?
classes << "disabled" if user.disabled?
if classes.any? # method return nil unless
classes.join(" ")
end
end
<%= content_tag :tr, :class => tr_classes(user) do -%> # if tr_classes.nil? blank <tr>
<td><%= user.name %></td>
<% end -%>
you could try a helper method, something like
def user_table_row(user)
css = ""
css = "#{css} error" if user.company.nil?
css = "#{css} disabled" if user.disabled?
content_tag :tr, class: css
end
not sure how well this will work in the case of a table row, as you will want to nest td inside it
UPDATE: here is updated version yielding the block of td code
def user_table_row(user)
css = # derive css, using string or array join style
options = {}
options[:class] = css if css.length > 0
content_tag :tr, options do
yield
end
end
then in the view
<%= user_table_row(user) do %>
<td><%= user.name %></td>
<% end %>

Resources