In SQL I would do this:
SELECT minimummonths WHERE name = "gold"
I want to do the same in Ruby on Rails and have the following in the new section of my orders controller:
#plan = params[:plan]
#Payplanrow = Payplan.where(:name => #plan).minimummonths
I then try to display #payplanrow in my page using <%=#Payplanrow %> but it doesnt work. I get the error:
undefined method `minimummonths' for #<ActiveRecord::Relation:0x007fe30f870ec0>
I want to print the minimummonths value for the plan selected. There will only ever be one row of data corresponding to the #plan value.
I'm pretty new to Ruby on Rails so I'm just trying to get a pointer in the right direction. I looked everywhere but there doesn't seem to be an example of this.
The problem is Payplan.where(:name => #plan) is returning an array of Payplan objects. Assuming you are using Rails 3, you can read more about it in "Active Record Query Interface".
But, if you are certain that your query is returning only one record you could do:
#Payplanrow = Payplan.where(:name => #plan).first.try(:minimummonths)
The Rails way is to have a scope in your model:
class Payplan < ActiveRecord::Base
scope :by_name, lambda {|name|
{:conditions => {:name => name}}
}
end
#controller
#Payplanrow = Payplan.by_name(#plan).first.try(:minimummonths)
Although it's not really optimal, you can do:
#Payplanrow = Payplan.where(:name => #plan).first.minimummonths
You can use pluck to get only the minimummonths value :
minimummonths = Payplan.where(:name => #plan).pluck(:minimummonths).first
Instead of using where then first, it's better to use find when you are expecting a single record.
#Payplanrow = Payplan.find_by_name(#plan).try(:minimummonths)
That should be:
Payplan.where(:name => #plan).first.minimummonths
Related
So I set up a postgres server and have it working with hstore values.
As of right now, I have a table books, structured with
name:string data:hstore
I have created a sample entry to test:
Book.create(:name => "My First Book", :data => {'author' => 'Kevin', 'pages' => 368})
I have loaded the data into a variable:
#book = Book.where("data ? :key", :key => 'pages')
(just to test, i realize this query would serve no real purpose...)
I print the data as JSON and this works fine, the entry is found and displayed. However, what I am trying to do is access, say the pages, an hstore value. I did some research and found
#book.data['pages']
However, when i try to run this, I get
undefined method `data' for #<Book::ActiveRecord....
Any and all help is greatly appreciated!
The Active Record where will give you an array even if there is only 1 value.
You can do
#book = Book.where("data ? :key", :key => 'pages')[0]
to get that record
and then
#book.data
will work as desired.
If you might get multiple records and just using the first found is ok you could also use:
#book = Book.where("data ? :key", :key => 'pages').first
#book.data
or just
#book = Book.where("data ? :key", :key => 'pages').first.data
After fiddling around, i found that I simply needed to call:
#book[0].data
I've been reading Checking for nil in view in Ruby on Rails but I'm struggling to implement the marked solution.
I want to only load a graph in my View if a result set is not nil.
Controller:
#statistics = # ...my ActiveRecord query...
Helper:
def show_stats(statistics)
if statistics.pluck(:count)
image_tag(Gchart.line :size => '640x260',
:stacked => false,
:title => '',
:data => [statistics.pluck(:count)],
:legend => ['Stats'],
:bar_colors => ['3300CC', '3399FF'],
:axis_with_labels => ['y'])
end
end
View (HAML):
= show_stats(#statistics)
Currently when there are no statistics, I get an error. I want the View to not render the graph if there are no statistics. What am I doing wrong in the helper?
Error:
undefined method `-' for nil:NilClass
on the line where I call the helper.
if i understand correctly statistics.pluck(:count) will always return an array consisting of values of count attribute for each record found.
in ruby empty array evaluates to true, you might try to rewrite that if line like this:
if statistics.pluck(:count).any?
in fact it's good idea to cache that value and not fetch it from db again few lines below:
if (counts = statistics.pluck(:count)).any?
...
:data => [counts]
...
end
also i assume :data option wants array of values and not array of array of values so the final version would be:
if (counts = statistics.pluck(:count)).any?
...
:data => counts
...
end
P.S. if you still have an error - please share a full backtrace with us, knowing only "undefined method" doesn't tell much
Why not check for #statistics in your view like follows:
= show_stats(#statistics) if #statistics
Did you try this?
= show_stats(#statistics) unless #statistics.nil?
I'm trying to get these statements to work:
#all_ratings = ["G","PG","PG-13","R"]
#valid_ratings = params["ratings"]
#movies = Movie.find(:all , :conditions => {#valid_ratings[:rating.upcase] => "1"} )
but I am getting the error:
undefined method `to_sym' for nil:NilClass
when I should be getting a match.
An example input is:
"ratings"=>{"PG-13"=>"1"}
Where am I going wrong?
More info:
The table has three fields, the title, release date, and rating, and is very simple. The options for rating are stated above in #all_ratings.
Rails 3.x:
#all_ratings = ["G","PG","PG-13","R"]
#valid_ratings = params["ratings"]
# Is #valid_ratings the same as you example, "ratings"=>{"PG-13"=>"1"}?
# It would be easiest to pass a subset of #all_ratings such that the params
# get converted to something like this: "ratings"=>["G", "PG"]
Movie.where(:rating => valid_ratings).all
# SQL: SELECT * FROM movies WHERE rating IN ('G','PG')
I am not sure what you are trying to with :rating.upcase. Is there a variable named rating? :rating is a symbol. upcase is not a method on Symbol.
It tells you that you #valid_ratings in nil
You probably trying doing this?
#valid_ratings = Rating.find(params["ratings"])
In my view page, i am using form_tag to create a form which will pass a string of ids from a hidden field to the controller code.
In my controller code, i am looping through an array of ids to update each record containing that id in the Expression table. But the code below does not seem to work.
I would really appreciate it if somebody could give me some suggestion regarding what is wrong with the code below.
def update_expression
#emi_ids_array = params[:emi_ids].split(/,/)
#sub_id = params[:sub_id]
#emi_ids_array.each do |emi_id|
#existing_exp = Expression.find(:first, :conditions => [ "EXT_EMI_ID = ? and EXT_SUB_FK = ?", emi_id, #sub_id])
#expression = #existing_exp.update_attributes(
:EXT_SUB_FK => #sub_id,
:EXT_PRESENCE => "present",
:EXT_STRENGTH => "weak",
:EXT_EMI_ID => emi_id
)
end
end
Try converting the array of ID's (and the sub_id) to integers.
Is it the finding of the object that fails, or the update? Output the #expression.errors after the update call to see if there are any validations failing.
Is there a reason for all the instance variables? You don't need the #'s if the variable doesn't go beyond that method. Also the #expression item seems superfluous, you're just duplicating the #existing_exp object, you don't need to put the return into a new object, especially if it's replaced each time the loop runs anyway.
Found a temporary solution. 'update_attributes' does not seem to work, so i opted for 'update_all' attribute
Expression.update_all({:EXT_PRESENCE => "present", :EXT_STRENGTH => "weak"},['EXT_EMI_ID = ? and EXT_SUB_FK = ?', emi_id, #sub_id])
Hopefully, it might be useful to someone else
I want to extract the id number of a unique record, that resides in a different controller as an integer, so I can save it as part of a new record in a new controller.
I can't seem to get the id to shed it's 'Array' attribute.
I've been using this:
class MessagesController < ApplicationController
def incoming
a = Group.where("name = ?", name).map { |n| n.id }
group_number = a.id
puts "#{group_number} is the number!"
end
output is always [2] or [3] or whatever.
adding this doesn't seem to cure it
group_as_int = group_number.to_i
Lastly, the reason I'm doing all this is to save that group number as a new record in a third controller, like this:
Subscriber.create(:group_id => group_number, :active => "1")
or
Subscriber.create(:group_id => group_as_int, :active => "1")
Of course, the create balks when I try to pass an array into the create function.
Thoughts?
You are trying to put business logic into the controller.
Try to refactor your methods and put them into your models instead.
Beside that you get the number in the following way:
group = Group.where("name = ?", name).first
group_number = group.id if group.present?
You might want to try .first to get the integer out of the array.
I will try to explain from your code what you did wrong.
The first line:
matching_group_ids = Group.where("name = ?", name).map { |n| n.id }
You called it a, but i prefer more verbose names. matching_group_ids now holds an array of id's. To get the first value of this array, the easiest solution is to just write
group_number = matching_group_ids[0]
or, more readable:
group_number = matching_group_ids.first
Mind you: you should test that the returned array is not empty.
Hope this helps.