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
Related
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?
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
My database will not update my active_quests. All I am trying to do is replace one array of hashes with another, updated array of hashes. I assumed would be the simplest way of handling this. Here's the code:
# construct the query
query = Player.where( :_id => player_id).fields( :xp, :lvl_prgrssns, :active_quests, :completed_quests )
# get the player
player = query.first
if !player.nil?
return_val = player.set( :active_quests => [{"quest_id" => "123"}, {"quest_id" => "456"}])
logger.debug "return_val = "+return_val.to_s # comes out as 180
end
My understanding is that, if the return from a set is positive, that means that the set was successful. It returns as 180 in this simplified case but the active_quests never get updated on the player. I can go into the mongo console and execute this:
db.players.update({_id:ObjectId("50756b1896f4f5121a00000a")}, {$set:{active_quests:[{"quest_id":"1"}, {"quest_id":"2"}] }});
and active_quests will update as expected but no matter what I try in rails the update appears to go through but nothing updates.
Here are some of the many alternatives I have tried (all have been tried with and without .to_mongo and with and without player.save after them):
Player.where( :_id => params[:player_id] ).update(:active_quests => active_quests_list.to_mongo)
player.update_attributes(:active_quests => active_quests_list.to_mongo)
player_update = player.as_json
player_update["active_quests"] = active_quests_list
player.update_attributes(player_update)
return_val = query.update( "$set" => {:active_quests => player.active_quests.to_mongo} )
return_val = query.update( {:_id => params[:player_id]}, {"$set" => {:active_quests => active_quests_list.to_mongo}})
I'm hoping someone here might know what I am doing wrong.
After further investigation, it turns out that this was a problem relating to how the player variable was being updated outside of the function.
The following lines will update the record in this case (both in-memory and in the database)
player[:active_quests] << #active_quests_list
player.push_all(:active_quests => player.active_quests)
However, the player variable was local to this function in this case, and was being updated again after the function returned.
This was only discovered after careful examination of the output of "mongod -vvvvv".
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'm trying to use RoR for something simple and I'm having some trouble picking up the basics. My closest background is ASP.NET MVC but I'm finding all of the RoR tutorials focus on what rails is really good at (scaffold stuff) but not how to make your own actions and get them to do stuff with parameters etc. (something trivial in ASP.NET MVC).
At the moment I am trying to get two random elements out of the model.
I think I'm dealing with an ActiveRecord collection of some sort?
I have read that there is a .rand method somewhere on collections/arrays, although other places suggest that rand is just a method for getting a random number up to a certain count. I can't even get the following code to work:
def index
#items = Array.new(Item[0], Item[0])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #domain }
end
end
Anything that can help with this, and ideally help with further patching from ASP.NET MVC to RoR would be really appreciated.
To retrieve two random items from an ActiveRecord model:
#things = Thing.all(:order => 'RANDOM()', :limit => 2)
If you want 2 random items from the database, then ask the database for 2 random items:
#items = Item.find(:all, :limit => 2, :order => "RANDOM()")
There's no point loading all of the Items from your system if you're only using 2, that's a waste.
If you do already have an array from somewhere else that you need to get random values from, then Rails adds a rand method to the Array class:
#items = [my_arr.rand, my_arr.rand]
I don't know what you were trying to do with Item[0] but that doesn't do anything meaningful in Rails.
What does your model look like? I'm not sure what you're trying to do with Item[0] there. For randomizing your array you could do something like this:
#items = ["item1", "item2", "item3"].sort_by {rand}
then you could just do #items[0] and #items[1] to get 2 items of the randomized array.
As for params, you can get any form variables or request params from the query string by using the params hash:
params[:user]
The symbol name is just the name of the form field or param in the query string.
Rails controllers usually contain one or more restful actions (index, show, new, create, delete, edit, update) if you've routed it as a resource, but you adding your own actions involves just adding a new method to your controller, routing that action in the routes.rb, and creating a view with with the name of that action.
More info on your model & what you are trying to accomplish would help, but if you are trying to pull a random record from a database like sqlite, you can do something like:
#item = Items.find(:first, :order => 'RANDOM()')
Where Items is your model class. The 'RANDOM()' is just a string handed to the database to tell it how to sort, so you'll have to adjust to match whatever database you're using.
With a Mysql Database use RAND() and not RANDOM()
#items = Item.find(:all, :limit => 2, :order => "RAND()")