Simple calculation and store to database in ruby - ruby

I'm trying to do a simple calculation with two submitted form variables then store all three variables in the database. Each variable is a column in my database.
E.G.
somedbfield = ( item_1 * item_2 ) + 2
How would I upon form submit, somedbfield, item_1, item_2 save in the Test database? all three items are being validated with validates_numericality_of in the model and they should all be integers. Here's just my basic code to find the test.id from the form submitted, but I don't know how to create a calculation using the form values and then submit all three values to the database:
class Test_Controller < ApplicationController
def update
#test = Test.find(params[:id])
respond_to do |format|
if #test.update(test_params)
format.html { redirect_to('index', :notice => 'User was successfully updated.') }
format.json { respond_with_bip(#test) }
else
format.html { render :action => "edit" }
format.json { respond_with_bip(#test) }
end
end
private
def test_params
params.require(:test).permit(:item_1, :item_2, :somedbfield)
end
end
This is a much more simpler version of a question that I previously asked but couldn't get any answers for, so i'm trying just to simplify and work forward from there.
Thank you!!

The way I see it, your update method simply retrieves an instance of the model and saves it without doing anything.
To update the database, you would need to pass in the parameters to the instance and then save it:
item_1 = params[:item_1]
item_2 = params[:item_2]
somedbfield = ( item_1 * item_2 ) + 2
#test.update(:item_1 => item_1, :item_2 => item_2, :somedbfield => somedbfield)

you should use the params[:symbol] syntax for this. You can use:
#test.item_1=params[:item_1]
#test.item_2=params[:item_2]
#test.somedbfield=params[:item_1]*params[:item_2]+2
#test.save
Let me know if this helps.

Related

Update users table when running create action of different model

Just to show you how I got to this point:
Every user has many profiles. Every profile has type recognized by single table inheritance(amateur, professional, and some other). I need to store current_profile somewhere and somehow.
Professionals Controller
class ProfessionalsController < ApplicationController
def create
#professional = Professional.new(professional_params)
#user = current_user
#professional.user_id = current_user.id
#update_current_profile = User.update(#user, {:current_profile => #professional.id})
if #professional.save
...
else
...
end
end
private
def professional_params
params.require(:professional).permit(:id, :username, :user_id)
end
end
This is meant to update current_profile of user to the newly created professional profile and do some staff then.
When the profile is created current_profile is set(updated) to NULL. If I change :
#update_current_profile = User.update(#user, {:current_profile => #professional.id})
to something different, for example:
#update_current_profile = User.update(#user, {:current_profile => #professional.user_id})
or
#update_current_profile = User.update(#user, {:current_profile => 3})
it stores data in User.current_profile perfectly.
I was trying #professional without an .id too. Why is this doing so?
Another question is. Is this the best way to store current_profile of user? Would you recommend me any better/safer/more efficient solution?
Thanks all of you guys.
#professional is a new, unsaved record and therefore does not have an id yet. Can only update the current_profile once the #professional record was saved.
Just reorder the lines a bit and it should work:
def create
#professional = Professional.new(professional_params)
#user = current_user
#professional.user_id = current_user.id
if #professional.save
#update_current_profile = User.update(#user, {:current_profile => #professional.id})
# ...
else
# ...
end
end
Just another tip: You use many instance variables (the one with the #) in this method. I do not know enough about your code, but I would suggest to look if some of them can be replaced with local variables. Rule of thumb: Only use instance variables in controllers when you want to share that variable with another method or the view.

Store calculation in database using variables submitted in a form

I'm submitting a simple form with variables that are named in the database.
I am trying to:
Store the submitted variables in the database (which works fine)
Run a calculation, then store that value into the database
No matter what I try I either get an error or 'nil' (upon #kcmil.inspect) as my result for #kcmil. I'm assuming in my current code i'm not passing the variables to the model, but it doesn't work even when it's in the controller.
I'm at a loss here. My variables that are submitted in the form store just fine as expected. I just want to be able to use submitted variables from a form (that are also database items that get stored upon submission) and before saving to the database (or after, should it matter?) run a calculation and store the result in a database item (that is not previously called in or saved from the form). Does that make sense? Any help or hints are GREATLY APPRECIATED!!
Here are my current calculators_controller create and edit actions:
def create
#calculator = Calculator.new(calc_params)
if #calculator.save
flash[:notice] = "Calculation created successfully."
redirect_to(:action => 'index')
else
render('new')
end
end
def update
#calculator = Calculator.find(params[:id])
if #calculator.update_attributes(calc_params)
flash[:notice] = "Calculation updated successfully."
redirect_to(:action => 'index', :id => #calculator.id)
else
render('edit')
end
end
private
def calc_params
params.require(:calculator).permit(:subsection, :amps, :volts, :distance, :vdrop, :phase, :kcmil, :section_id)
end
Here's my model
class Calculator < ActiveRecord::Base
before_create :kcmil_calc
def kcmil_calc
if #phase == 1
self.kcmil = ((13 * #distance.to_i * #amps.to_i ) / #vdrop.to_i).round(2)
else
self.kcmil = ((12.9 * #distance.to_i * #amps.to_i ) / #vdrop.to_i).round(2)
end
end
end
I HAVE IT! I HAVE IT!
before_update :defaults
def defaults
if self.phase == 1
self.kcmil = ((12.9 * distance * amps) / vdrop).round(2)
else
self.kcmil = ((13 * distance * amps) / vdrop).round(2)
end
end
solved it! I had to call self.phase instead of #phase and change before_create to before_update to get it to work . No change in the controller required. Dang - one simple #! I also removed the to_i because it's not needed since my views prevent me from submitting anything other than integers.

how to differentiate searched or created by first_or_create

I want to differentiate searched or created by first_or_create.
record = MasterRecord.where(:name=>'test_data').firest_or_create
# and i want differentiate searched or created like this.
# but there is no created_record? method
if record.created_record?
render :status=>200, :json => record.to_json
else
render :status=>409, :json => record.to_json
end
how do I do this?
A workaround will be to use first_or_initialize instead first_or_create and then use the new_record? as follows:
record = MasterRecord.where(:name=>'test_data').first_or_initialize
created_record = record.new_record?
record.save! if record.new_record?
if created_record
render :status=>200, :json => record.to_json
else
render :status=>409, :json => record.to_json
end
If record can't be found the return will be [], so you can play with tap.
Something like this:
created = false
record = MasterRecord.where(:name=>'test_data').tap {|x| created = true if x.empty?}.first_or_create
if created
...

Trying to populate gmaps4rails with multiple json strings in one page

I hope I am asking this right, so please let me know if I'm way off.
The problem is trying to build a homepage that draws from multiple controllers, to display the nearest locations from multiple controllers, ie. food, businesses, ect.
Right now the individual listings pages have maps drawn from their respective
#json = Controller.all.to_gmaps4rails
How would I do something like :
#json = Controller1 Controller2 .all.to_gmaps4rails
I hope this isnt a noob question and I'm just having a bad day. Thanks guys!
edit 12.5.2011 #seanhill - this is one of the models, the other sections are very close to this format. First off, I wasn't even sure if my homepage requires it's own model, as it doesn't interact with the db at all, more pulling data from controllers that do the work. Thanks for the response Sean!
class Dining < ActiveRecord::Base
validates_uniqueness_of :name, :message => "already exists"
attr_accessible :name, :address, :cuisine, :latitude, :longitude, :about, :facebook, :twitter, :phone, :website
geocoded_by :address
after_validation :geocode, :if => :address_changed?
acts_as_gmappable :process_geocoding => false
def gmaps4rails_address
"#{self.address}"
end
def gmaps4rails_infowindow
"<h3>#{self.name}</h3><br /><h5>#{self.cuisine}</h5>"
end
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
Try this
holder = Controller1.all
holder << Controller2.all
#json = holder.flatten.map{|h| {lng: h.longitude, lat: h.latitude, class: h.class.to_s}}.to_json
Make sure to change longitude and latitude based on your column names and use js to manipulate the markers based upon class.
As the #Sean Hill said you shouldn't be calling .all on controllers but I think you have a slight misunderstanding of how things are working. Assuming you have a Model called Dining and another called Shop, when you call Dining.all or Shop.all inside class DiningsController < ApplicationController, you are calling .all on either the Dining Model or the Shop Model not on the DiningsController.
The information you display through a controller is only limited by the methods you call in it although it is best practice ensure the main focus of the information displayed is related to the respective controller.
So what you are really trying to do is get the records from multiple models and group them together to display them in a single map.
With that said the answer should read something like this
holder = Dining.all # Takes all Dining records returned as an array and sets them to holder variable
holder << Shop.all # Pushes the Shop records array into the holder with the dining records
holder.flatten!# Next we flatten the array so we only have a single array.
# Then we use the map method to run the given code one time for each instance
# in the holder array to extract the info we need. The results for every instance
# in holder are returned in an array which we then convert to_json.
#json = holder.map{|h| {lng: h.longitude, lat: h.latitude, class: h.class.to_s}}.to_json
#json1 = something.to_gmaps4rails
#json2 = something.to_gmaps4rails
#json = (JSON.parse(#json1) + JSON.parse(#json2)).to_json
I populated the map with my initial data of festivals, and then added the rides to it with javascript with this code,
<% content_for :scripts do %>
<script type="text/javascript">
Gmaps.map.callback = function() {
$.getJSON('/rides_gmap', function(data){
Gmaps.map.addMarkers(data);
});
}
</script>
<%end%>
In the rides controller I had this
def rides_gmap
#rides = Ride.all
#json = #rides.to_gmaps4rails do |ride, marker|
marker.infowindow render_to_string(:partial => "/rides/infowindow", :locals => { :ride => ride})
marker.picture({
'picture' => view_context.image_path("orange-dot.png"),
'width' => 20,
'height' => 20
})
marker.title "#{ride.address}"
marker.json({:ride_id => ride.id, :ride_festivaltype => ride.festival.festivaltype
end
respond_with #json
end
I hope this helps.

Rails - appending query parameters to existing URL

I have an application controller method called redirect back or default which is used to redirect users to the page they were requesting after login
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
I would like to be able to optionally add URL parameters (for some analytics tracking) to the url, but am not sure of the best way. I'd like to change the method signature to this
def redirect_back_or_default(default, params=nil)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
and somehow attach the params to the existing URL. Is there a standard ruby or ROR way to do this? I could obviously brute force check to see if there is a query string as part of the URL with regex and manually build the query string, but I was hoping there is an easier standard way of doing this.
From here:
To pass parameters with redirect_to
you simply add them. Like ...
redirect_to :controller => 'another', :action => 'def', :param1 => 'some', :param2 => 'thing', :param => 'else'
standart approach
def redirect_to_back_or_default(default = "/")
back = case request.env["HTTP_REFERER"]
when request.fullpath
default
when nil
default
else
:back
end
redirect_to back
end

Resources