I am using Act_as_votable to implement like/dislike voting system. It works just perfect.
But now I am facing problem to blacklist exact that item that has received at least 30 downvotes.
I have model Advertisement. That has column in_blacklist with default value false.
I added in_blacklist field as permitted in Advertisement controller.
I have tried this so far.
In view:
<%= link_to "Like", like_advertisement_path(#advertisement), method: :put %> <%= #advertisement.get_likes.size %>)
(<%= link_to "Dislike", dislike_advertisement_path(#advertisement), method: :put %> <%= #advertisement.get_dislikes.size %>)
In controller:
def downvote
#advertisement.downvote_from current_user
flash[:notice] = 'Downvote added.' if #advertisement.vote_registered?
if #advertisement.get_dislikes.size == 30
#advertisement.in_blacklist = true
flash[:notice] = "#{#advertisement.name } added to blacklist. Information sent to #{#advertisement.user.email } "
respond_with(#advertisement)
else
respond_with(#advertisement)
end
end
So when I hit 30th dislike, there is no error messages. And when I check if the boolean has changed, but no it is still false.
You forgot to save the object.
def downvote
#advertisement.downvote_from current_user
flash[:notice] = 'Downvote added.' if #advertisement.vote_registered?
if #advertisement.get_dislikes.size == 30
#advertisement.in_blacklist = true
#advertisement.save # there you go!
flash[:notice] = "#{#advertisement.name } added to blacklist. Information sent to #{#advertisement.user.email } "
respond_with(#advertisement)
else
respond_with(#advertisement)
end
end
Related
I have template_sections and sections and on a button click in my view I want
a) get all template_sections with a specific template_id, send them to the sections_controller
or
b) the section_controller method transform should get the template_sections there
and
iterate over them and create a new section object for each one of them, where I would set is_template = 0 and template_id = nil and save them.
View:
<div class="col-2 deploy-template">
<%= button_to 'Deploy Template', transform_sections_path, method: :post, *{call controller's method or send objects from here to transform method}*, remote: true, type: 'button', class: "btn btn-secondary btn-sm ml-0 mr-4" %>
</div>
Controller:
def new
#section = Section.new
if params[:is_template]
date = (Time.at(params['day'].to_i*86400-1)).strftime("%Y-%m-%d")
#section.starts_at_datetime = (date + ' ' + params['time']).in_time_zone rescue nil
else
#section.starts_at_datetime = (params['date'] + ' ' + params['time']).in_time_zone rescue nil
end
respond_to do |format|
format.js
end
end
def create
#section = Section.new(section_params)
#section.account_id = session_account_id
#section.is_template = true if params[:section][:is_template] == 'true'
#section.template_id = params[:section][:template_id]
respond_to do |format|
if #section.save
format.js
flash.now[:success] = "saved successfuly"
create_event #section, "create", "Create"
else
flash.now[:danger] = "#{#section.errors.full_messages}"
format.js { render 'layouts/notifications' }
end
end
end
def transform
template_sections.each do |template_section|
#save each template_section with is_template = 0 and template_id = nil
end
What you can do is pass your template sections to your controller through the params hash like so:
<%= button_to 'Deploy Template', method: :post, transform_sections_path(template_sections: [YOUR ARRAY VARIABLE HERE]), remote: true, type: 'button', class: "btn btn-secondary btn-sm ml-0 mr-4" %>
Your template sections should then be available through params[:template_sections] inside of your controller for you to do whatever you feel like doing, (I am assuming post: template_sections_path points to the transform action in your controller).
def transform
template_sections = params[:template_sections]
template_sections.each do |template_section|
#save each template_section with is_template = 0 and template_id = nil
end
I don't know what your TemplateSection model looks like so I will refrain from writing controller code that won't work, but hopefully once you have the data in your controller you will be able to work through it, and if not I am happy to help with a little bit more information.
As an additional note, "method: :post", and "type: button" seem redundant when using a button_to tag as those are the defaults, you can remove them unless you have a specific reason for having them.
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 trying to set up the Mandrill API to send an email when a user clicks a button, but I cannot seem to get it to send. The email will send perfectly fine from the console, so I know it is not a problem with the template (Devise emails also send find).
I think it is to do with how I have set it up in the controller but I cannot find any help on where I should put it instead.
Here is the code from the controller:
def attending
#event = Event.find(params[:id])
type = params[:type]
if type == "attending" && #event.space != 0
current_user.attending << #event
#event.space = #event.space - 1
#event.save
AdminMailer.new_attending(#event.user, current_user)
redirect_to :back, notice: "You've joined the group. Your number will be sent to #{#event.user.name}"
else type == "unattending"
current_user.attending.delete(#event)
redirect_to :back, notice: "You've removed yourself from the group"
end
end
Here is the admin_mailer.rb
class AdminMailer < ActionMailer::Base
require 'mandrill'
def mandrill_client
#mandrill_client ||= Mandrill::API.new MANDRILL_API_KEY
end
def new_attending(creator, user)
template_name = "new-attending"
template_content = []
message = {
to: [{email: creator.email, name: creator.name}],
subject: "Someone wants to go riding with you!",
merge_vars: [
{rcpt: creator.email,
vars: [
{name: "CREATOR_NAME", content: creator.name},
{name: "USER_NAME", content: user.name},
{name: "USER_NUMBER", content: user.number}
]}
]
}
mandrill_client.messages.send_template template_name, template_content, message
end
end
And here is the link they click in the view.html.erb that should send the email:
<td><% if event.user != current_user && event.space != 0 && user_signed_in? %>
<% unless event.attendees.include?(current_user) %>
<%= link_to "Join", attending_event_path(event, type: "attending"), class: "btn btn-primary btn-xs", method: :put %>
<% end %>
<% end %></td>
Any help in figuring out why it's not sending would be great! As I said, it works in the console when I type:
AdminMailer.new_attending(#event, #user)
Please replace following code.
AdminMailer.new_attending(#event.user, current_user)
with
AdminMailer.new_attending(#event.user, current_user).deliver
I hope this will work.
I trying rewrite some data in model. Change_settings is GET-method, update_settings is POST. After click SUBMIT happens nothing. Data not change. Help me, please( what's wrong?
controller
def change_settings
#vacation_days = current_company.vacation_days
#illnes_days = current_company.illnes_days
end
def update_settings
current_company.update_attribute(:vacation_days, :illnes_days)
current_company.save
redirect_to account_company_path, notice: t('company.settings_changed')
end
change_settings view
.company_settings
= form_tag update_settings_company_path do
= field_set_tag do
= label_tag 'vacation_days'
= text_field_tag :vacation_days
= label_tag 'illnes_days'
= text_field_tag :illnes_days
%br
= submit_tag t('common.save'), class: 'btn'
= link_to t('common.back'), account_company_path, class: 'btn'
routes
resource :company, only: :all do
get :account
get :change_settings
post :update_settings
end
replace:
current_company.update_attribute(:vacation_days, :illnes_days)
current_company.save
with:
current_company.update_attributes(vacation_days: params[:vacation_days], illnes_days: params[:illnes_days] )
Basically you were not taken data sent from client into account
I have form that create two objects and save them to database.
I want to do next things:
save data in database (booth objects)
validate fields (I have validation in model)
and if validation fail, I want to populate fields with entered data
edit action for this form
Problems:
If I use #report I get:
Called id for nil, which would
mistakenly be 4 error
(can't find object). I have in controller, in encreate action #report = ReportMain.new and in action that render that view.
When I use :report_main (model name) it works, it save data to database, but I can't get fields populated when validation fails.
Questions:
What to do with this two models to make this to work (validation, populating fields, edit)?
Can you give me some advice if approach is wrong?
My view looks like this:
<%= form_for(#report, :url => {:action => 'encreate'}) do |f| %>
<%= render "shared/error_messages", :target => #report %>
<%= f.text_field(:amount) %>
<% fields_for #reporte do |r| %>
<%= r.check_box(:q_pripadnost) %>Pripadnost Q listi
<%= select_tag('nacinpakovanja',options_for_select([['Drveno bure', 'Drveno bure'], ['Kanister', 'Kanister'], ['Sanduk', 'Sanduk'], ['Kese', 'Kese'], ['Posude pod pritiskom', 'Posude pod pritiskom'], ['Kompozitno pakovanje', 'Kompozitno pakovanje'], ['Rasuto', 'Rasuto'], ['Ostalo', 'Ostalo']])) %>
<%= r.text_field(:ispitivanjebroj) %>
<%= r.text_field(:datumispitivanja) %>
<% end %>
<input id="datenow" name="datenow" size="30" type="text" value="<%= #date %>">
<div class="form-buttons">
<%= submit_tag("Unesi izvestaj") %>
</div>
<% end %>
encreate actin in ReportController:
def encreate
#report = ReportMain.new
#reporte = ReportE.new
#reportparam = params[:report_main]
#report.waste_id = params[:waste][:code]
#report.warehouse_id = Warehouse.find_by_user_id(current_user.id).id
#report.user_id = current_user.id
#report.company_id = current_user.company_id
#report.amount = #reportparam[:amount]
#report.isimport = false
#report.isfinished = false
#report.reportnumber = ReportMain.where(:company_id => current_user.company_id, :isimport => false).count.to_i+1
if #report.save
#reporte.report_main_id = #report.id
else
redirect_to(:action => 'exportnew')
return
end
#reporte.vrstaotpada = params[:vrstaotpada]
#reporte.nacinpakovanja = params[:nacinpakovanja]
#reporte.ispitivanjebroj = #reportparam[:ispitivanjebroj]
#reporte.datumispitivanja = #reportparam[:datumispitivanja]
#reporte.q_pripadnost = #reportparam[:q_pripadnost]
#reporte.datumpredaje = #date
if #reporte.save
redirect_to(:action => 'show', :id => #reporte.id)
else
redirect_to(:action => 'exportnew')
end
end
I think your problem in this case is that you use redirect_to instead of render. When you use redirect_to then you lose all the variables from your current action. I would probably do something like this in your encreate action:
if #reporte.save
render :show
else
render :exportnew
end
When you use render then it will use the variables from the current action but the view from the action you send to the render method. So when form_for is called with the #report variable, it is already populated with the values that was sent to encreate. Just make sure that you use the same variable names in the different actions but it looks like you do that already.