I'm trying to create a transaction log once a product is saved in my product controller. For some reason I'm getting an error when I try to save the transaction log. The product is being saved successfully.
Code:
def create
#product = Product.new(params[:product])
respond_to do |format|
if #product.save
ProductTransaction.create(
:product_id => #product.id,
:user_id => current_user.id,
:message => "Product created"
)
format.html {
redirect_to product_path(#product.id),
:flash => { :success => "Product was successfully created." }
}
else
format.html { render action: "new" }
end
end
end
Error:
PGError: ERROR: column "product_id" is of type integer but expression is of type character varying at character 117
HINT: You will need to rewrite or cast the expression.
: INSERT INTO "product_transactions" ("created_at", "message", "product_id", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
I don't understand the error above. I've double check my tables and the product_id is an integer. Also, I tried hard coding a number to see if I could just get it to save. That didn't work. I then removed all the parameters from the create function and still I got the same error. I even recreated the table from scratch and same result. ProductTransaction has no validation requirements. What am I doing wrong?
Code (Parameters removed):
def create
#product = Product.new(params[:product])
respond_to do |format|
if #product.save
ProductTransaction.create()
format.html {
redirect_to product_path(#product.id),
:flash => { :success => "Product was successfully created." }
}
else
format.html { render action: "new" }
end
end
end
Product Schema:
Product(id:integer, name:string, etc.)
Product Transaction Schema:
ProductTransaction(id:integer, user_id:integer, product_id:integer, message:integer)
Found my problem. I had to refresh my app for whatever reason.
ran the following and it worked:
touch tmp/restart.txt
Now if I could only get those two hours of my life back. :-)
Related
When updating a resource called JobsI want to copy some of the values from this update to some resources connected to this resource
Jobs has many Hours each hour has a period with 2 set of times. So if i update the job with these times i want them copied down to the periods
I tried this code in different variants but the periods entities dont get updated.
def update
#job = Job.find(params[:id])
respond_to do |format|
if #job.update_attributes(params[:job])
#job = Job.find(params[:id])
#job.hours.each do |hour|
logger.debug params[:job][:start1]
logger.debug params[:job][:end1]
hour.periods.first.start_time = params[:job][:start1]
hour.periods.first.end_time = params[:job][:end1]
hour.periods.last.start_time = params[:job][:start2]
hour.periods.last.end_time = params[:job][:end2]
end
#job.save
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
This should get you closer to telling which code is failing, but you could have all sorts of things going wrong in there. If this doesn't work, uncomment that binding.pry and make sure the hour attributes have updated Also, looks like you're getting #job twice? Give this a shot:
def update
#job = Job.find(params[:id])
respond_to do |format|
if #job && #job.update_attributes(params[:job])
logger.debug "Job updated attributes"
#job.hours.each do |hour|
hour.periods.first.update_attributes(start_time: params[:job][:start1])
hour.periods.first.update_attributes(end_time: params[:job][:end1])
hour.periods.last.update_attributes(start_time: params[:job][:start2])
hour.periods.last.update_attributes(end_time: params[:job][:end2])
# binding.pry
end
#job.save!
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
You could speed up the updates a little bit by calling update_column on the period records. i.e. hour.periods.first.update_column(:start_time, params[:job][:start_time]), but you would lose any validation or callbacks on your period model by doing so.
I have a Rails 3.2.18 app where I want to ship details of a call (includes name, age, and other information) to a recipient's phone that is already a field in the database.
So for instance a call has a unit assigned, and each unit has a medic (employee) assigned. In the medic model there's a phone field 281-444-555 (example number). What I want to be able to do in the calls controller is to send a SMS on create and update with the details of that call so it arrives on their phone as SMS.
I'm currently doing notifications to phones by using Email to SMS gateway 2813334444#vtext.com (example) using ActionMailer and it works "ok". But I really want to leverage Twilio.
Here's how I'm doing the mailer action to notify the medics of calls on create/update
calls_controller
def create
parse_times!
#call = Call.new(params[:call])
#call.dispatched_by = current_user.username
if #call.save
#call.send_mail(:new_call)
redirect_to calls_path, notice: "Call #{#call.incident_number} was successfully created.".html_safe
else
render :new
end
end
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
unless #call.call_status == "close"
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
call_mailer
def new_call(medic, call)
#call = call
#medic = medic
mail to: [#medic.medic_sms, #medic.medic_email], :cc => "noreply#company.com", subject: "New Call: #{#call.incident_number}"
end
def update_call(medic, call)
#call = call
#medic = medic
mail to: [#medic.medic_sms, #medic.medic_email], subject: "Updated Call: #{#call.incident_number}"
end
call model (mailer method)
def send_mail(mail_type)
units.each do |unit|
CallMailer.send(mail_type, unit.incharge, self).deliver
CallMailer.send(mail_type, unit.attendant, self).deliver
end
end
end
This is working just fine for mailing the phones and emails of the medics, but I would like to add something similar using Twilio where I can ship the call details to them via SMS in the create and update action.
If anyone can point me in the right direction, I'd appreciate it. I have a Twilio account already and would like to put it to good use.
Update 08/03/14
I think I figured this out and got it working in a basic fashion. But I'd like to see if there's someway to cleanly pass #call object data into the :body => section. Right now I'm having to iterate over the specific fields I want to send (which are about 10 different fields). It would be nice if I could create a partial or template and pass it to :body => similar to how ActionMailer works. Any thoughts?
calls_controller.rb (working)
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
unless #call.call_status == "close"
unless #call.unit_ids.empty?
send_sms
end
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
private
def send_sms
account_sid = 'AC5CCCCC'
auth_token = 'ATTTTT'
#client = Twilio::REST::Client.new account_sid, auth_token
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.incharge.medic_phone,
:body => "incident_number #{#call.incident_number} patient name #{#call.patient_name}"
)
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.attendant.medic_phone,
:body => "incident_number #{#call.incident_number} patient name #{#call.patient_name}"
)
end
end
Ok, I have this figured out now. I needed to do string interpolation in the :body element for Twilio to send the information out. Here is my final code and it's working and updated with a conditional to only fire Twilio if certain conditions are met.
calls_controller.rb
def update
parse_times!
#call = Call.find(params[:id])
respond_to do |format|
if #call.update_attributes(params[:call])
if !(#call.call_status == "close") && !(#call.unit_ids.empty?)
send_update_sms
#call.send_mail(:update_call)
end
format.html { redirect_to #call, notice: "Call #{#call.incident_number} was successfully updated.".html_safe }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
def send_update_sms
account_sid = 'AC5CCCC'
auth_token = 'ATTTT'
#client = Twilio::REST::Client.new account_sid, auth_token
#client.account.messages.create(
:from => '28140844444',
:to => #call.units.first.incharge.medic_phone,
:body => "Updated: #{#call.incident_number}/#{#call.units.map(&:unit_name).join(", ")}/#{#call.patient_name}/#{#call.patient_age}/#{#call.patient_sex.try(:sex)}/#{#call.nature.try(:determinant)}/#{#call.special_equipments.map(&:name).join(", ")}/#{#call.traffic_type}/#{transfer_from_address}/#{transfer_to_address} CHECK EMAIL FOR FULL CALL INFO"
)
#client.account.messages.create(
:from => '2814084444',
:to => #call.units.first.attendant.medic_phone,
:body => "Updated: #{#call.incident_number}/#{#call.units.map(&:unit_name).join(", ")}/#{#call.patient_name}/#{#call.patient_age}/#{#call.patient_sex.try(:sex)}/#{#call.nature.try(:determinant)}/#{#call.special_equipments.map(&:name).join(", ")}/#{#call.traffic_type}/#{transfer_from_address}/#{transfer_to_address} CHECK EMAIL FOR FULL CALL INFO"
)
end
def transfer_from_address
if #call.transferred_from.nil?
#call.transfer_from_other
else
#call.transferred_from.try(:facility_name) + ' ' + #call.transferred_from.try(:facility_address)
end
end
def transfer_to_address
if #call.transferred_to.nil?
#call.transfer_to_other
else
#call.transferred_to.try(:facility_name) + ' ' + #call.transferred_to.try(:facility_address)
end
end
I have the following code in my view:
<%= f.select :user_id, user_all_select_options, :include_blank => '--Select a name-----' %>
It displays a list of users with --Select a name----- at the top. When a user doesn't select a name from the list and leaves --Select a name----- selected I get errors because the user_id is blank.
For reference the helper method code looks like this:
def user_all_select_options
User.all.map{ |user| [user.name, user.id] }
end
My model is as follows:
class Parcel < ActiveRecord::Base
attr_accessible :parcel, :received_at, :received_by, :chilled, :courier, :location, :passed_to, :user_id, :user, :content, :localip
validates :user_id, :presence => true
belongs_to :user
end
For some reason the validation doesn't appear to be running, however if I select a user from the drop down and add a validation for an other field input the application correctly shows the user a message stating which field is incorrectly empty.
Interestingly if I leave the select drop down as --Select a name----- and keep the additional validation, an exception is thrown. It doesn't prompt for the missing fields it just errors.
Here is the record during an error (this record was from when I had a validates presence check on the location field:
{"utf8"=>"✓", "authenticity_token"=>"wM4KPtoswp3xdv8uU4UasdadNsZi9yFZmk=", "parcel"=>{"user_id"=>"", "received_by"=>"dan", "content"=>"", "chilled"=>"0", "courier"=>"", "location"=>"", "passed_to"=>"", "received_at(3i)"=>"9", "received_at(2i)"=>"2", "received_at(1i)"=>"2013", "received_at(4i)"=>"22", "received_at(5i)"=>"59"}, "commit"=>"Receive this Parcel", "action"=>"create", "controller"=>"parcels"}
Where should I start looking? The errors that show are when the controller does an unless check against the user.
The parcel controller create method looks like this:
def create
#parcel = Parcel.new(params[:parcel])
#parcel.localip = request.env['REMOTE_ADDR']
#parcel.received_by = #parcel.received_by.upcase
unless #parcel.user.mobilenumber.blank?
UserMailer.parcel_notification(#parcel).deliver
end
respond_to do |format|
if #parcel.save
format.html { redirect_to #parcel, notice: 'Parcel was successfully created.' }
format.json { render json: #parcel, status: :created, location: #parcel }
else
format.html { render action: "new" }
format.json { render json: #parcel.errors, status: :unprocessable_entity }
end
end
end
the reason why you're getting an exception when you don't select a user is this line
unless #parcel.user.mobilenumber.blank?
since the user_id is not set, #parcel.user is nil which causes the exception.
I suggest you move that inside the #parcel.save block.
def create
#parcel = Parcel.new(params[:parcel])
#parcel.localip = request.env['REMOTE_ADDR']
#parcel.received_by = #parcel.received_by.upcase
respond_to do |format|
if #parcel.save
unless #parcel.user.mobilenumber.blank?
UserMailer.parcel_notification(#parcel).deliver
end
format.html { redirect_to #parcel, notice: 'Parcel was successfully created.' }
format.json { render json: #parcel, status: :created, location: #parcel }
else
format.html { render action: "new" }
format.json { render json: #parcel.errors, status: :unprocessable_entity }
end
end
end
I have 2 models Users and Companies. (I'm using Devise for User)
User belongs to Company.
Company has many Users.
My User model includes an client_id column.
At the moment a User signs-up and is directed to the new_company_path where I'd like to create the relationship. (I'd prefer to keep this in 2 steps).
I know my code is wrong here in the companies_controller.rb — but it's where I'm at
def create
#user = current_user
#company = #user.Company.new(params[:company])
respond_to do |format|
if #company.save
format.html { redirect_to root_path, notice: 'Company was successfully created.' }
format.json { render json: #company, status: :created, location: #company }
else
format.html { render action: "new" }
format.json { render json: #company.errors, status: :unprocessable_entity }
end
end
Your problem lies within the line
#company = #user.Company.new(params[:company])
The association from user to company should not be accessed with a capital letter. To get the company associated with a user, you should call it like this:
#user.company
However, if there is no company associated then that method will return nil and you cannot call .new on nil so instead you need to call another method that Rails creates for you called build_company like this:
#company = #user.build_company(params[:company])
The last problem is that since it is the user that belongs to the company, the User instance needs to be updated with the newly created company_id and that will not happen if you only save the company. But when you use the build_company method, it will store the company instance in the association from User so if you call save on the user instead of the company it will create the company and link it to user, like this:
def create
#user = current_user
#user.build_company(params[:company])
respond_to do |format|
if #user.save
format.html { redirect_to root_path, notice: 'Company was successfully created.' }
format.json { render json: #user.company, status: :created, location: #user.company }
else
format.html { render action: "new" }
format.json { render json: #user.company.errors, status: :unprocessable_entity }
end
end
end
Your User model needs a company_id column. Then you can make a form to record that value wherever you like (i.e., on the new_company_path page).
I'm following along with railscast 196. I've got two levels of associations. App -> Form -> Question. This is the new action in the form controller.
def new
#app = App.find(params[:app_id])
#form = Form.new
3.times {#form.questions.build }
end
the view is displaying all 3 questions fine and I can submit the form... but nothing is inserted into the database for the questions. Here is my create action
def create
#app = App.find(params[:app_id])
#form = #app.forms.create(params[:form])
respond_to do |format|
if #form.save
format.html { redirect_to(:show => session[:current_app], :notice => 'Form was successfully created.') }
format.xml { render :xml => #form, :status => :created, :location => #form }
else
format.html { render :action => "new" }
format.xml { render :xml => #form.errors, :status => :unprocessable_entity }
end
end
end
Here are the params that are sent to my create method:
{"commit"=>"Create Form",
"authenticity_token"=>"Zue27vqDL8KuNutzdEKfza3pBz6VyyKqvso19dgi3Iw=",
"utf8"=>"✓",
"app_id"=>"3",
"form"=>{"questions_attributes"=>{"0"=>{"content"=>"question 1 text"},
"1"=>{"content"=>"question 2 text"},
"2"=>{"content"=>"question 3 text"}},
"title"=>"title of form"}}`
This shows that the params are being sent correctly... I think. The question model just has a "content" text column.
Any help appreciated :)
Assuming:
You have your form set up properly,
Your server shows your data is being sent to the new action, and
Your model doesn't contain callbacks that are blocking the save,
try changing:
#form = #app.forms.create(params[:form])
to
#form = #app.forms.build(params[:form])
Ok figured it out. Turns out I should have been looking at my console a little more. The error it was hanging up on when trying to insert questions into the db was "Warning: can't mass assign protected attributes :questions_attributes". Adding this into the accessible attributes did the trick.
class Form < ActiveRecord::Base
belongs_to :app
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions
attr_accessible :title, :questions_attributes
end