How to find a record that wasn't saved yet in Rails? - sql

Say I have a record called Post that has many comments.
Now I run the following code:
p = Post.new
p.comments.build(:title => 'great')
I would now like to locate that comment by its title.
If the record was saved, I could do something like
p.comments.find_by_title('great')
But since it isn't saved yet, that's going to return nil (because it actually runs an SQL query)
Is there a way to locate this record before it's saved?
Thanks!

comment = p.comments.build(:title => "great")

great_comment = p.comments.detect{|c| c.title == 'great'}

Just write:
new_comment = p.comments.build(:title => 'great')
and new_comment will be the newly added comment.
Or, you could do something like:
new_comments = p.comments.select{|x| x.new_record?}
which would give you an array with all the unsaved comments.

Related

How to get the org_id from a webhook?

When a Webhook is triggered, is there a way to get the org_id from which it was fired? (Aside from climbing up the triggered item)
The only solution I found so far is:
PodioItem::get($item_id); to get the space_id
PodioSpace::get($space_id); to get the full
PodioOrganization::get_for_url($attributes = array()); I get the org_id.
See the "Bundling responses using fields parameter" section at the very bottom of https://developers.podio.com/index/api on how you can use the fields query parameter to include more data. There's even an example that goes almost all the way for you (it walks up to the space level, but you can just tack the org onto it):
/item/{item_id}?fields=app.view(full).fields(space.view(full))
For podio-php you can do:
$item = PodioItem::get($item_id, array('fields' => "app.view(full).fields(space.view(full))"));
Use PodioItem::filter instead of PodioItem::get, I'm pretty sure that you'll have the expected results, so try this:
$item = PodioItem::filter($item_id, array('filters' => "app.view(full).fields(space.view(full))"));
Hope it helps!

Locate database entry based on ID from another database entry in rails

I've been digging around a little trying to figure out how I should locate the "tweet_id" in my #savedtweets table and then locate that same "tweet_id" in my #newtweets table from a controller, so far I'ved tried something like this;
CONTROLLER
#stweet = Savedtweet.find(params[:id])
#newtweet = Newtweet.where(:tweet_id => #stweet.tweet_id)
#newtweet.status = 'new'
#newtweet.save
Basically I need to change the string "saved" in my Newtweets table to "new" based on the current Savedtweet ID. I just can't figure it out. If I do the following in console;
#stweet = Savedtweet.first
#newtweet = Newtweet.where(:tweet_id => #stweet.tweet_id)
It finds the right one. I've got to be close just not there yet. :)
You could do:
Newtweet.find_by_tweet_id(#stweet.tweet_id).update_attribute(:status, 'new')
The reason your code isn't working is because Newtweet.where() returns an array of objects. It should be Newtweet.where().first, though Newtweet.find_by_tweet_id is the preferred method.

How to search using acts-as-taggable using conditions

I have a materials model which has a search form. The search action looks a bit like this:
def search
conditions = {}
conditions[:version] = 'master'
conditions[:status] = 'shared'
conditions[:targ_lang] = params[:targ_lang] unless params[:targ_lang].blank?
#results = Material.find(:all, :conditions => conditions)
end
I have added the acts-as-taggable gem and it works fine to save the tags but I'm having trouble adding it to the search form. The documentation states that to find Materials with the tags you can use this code:
Material.tagged_with(["awesome", "cool"], :match_all => true)
But I don't know how to add this condition to the conditions.
Update
#results = Material.where(conditions) && Material.tagged_with(params[:tag_list])
This works provided tags are used but it doesn't work if the tag list is blank so I need a condition as with the other conditions above that the Material.tagged_with ... part is only necessary if the field is not empty.
Update 2 - Bad Solution
This works but it's not very elegant is it?
if params[:tag_list].blank?
#results = Material.where(conditions)
else
#results = Material.tagged_with(params[:tag_list]).where(conditions)
end
This code won't work for you?
Material.where(conditions).tagged_with(['awesome', 'cool'], :match_all => true)
Or the inverse order:
Material.tagged_with(['awesome', 'cool'], :match_all => true).where(conditions)
UPDATE
Reading the docs on the act-as-taggable-one on github, there is a option named :any. Maybe you can try to use it. I don't have a project i could do some testing, but maybe a code like:
Material.tagged_with(['awesome', 'cool', '', nil], :any => true).where(conditions)
Give it a try.

Add data from one table to another in ruby on rails

In my current project, I have to get some data in a column of one table and put them to the 2nd table. The first table data have been saved as hash as follows:
---
- werweqr
- test
- B1
- B2
- B3
- xvxczv
I write the following code in the migration file to add the data from the first table to the 2nd table. But the data are not sending from the first to second.
#scenario_response = ScenarioResponse.where("selected_barriers != ?", "");
#scenario_response.each do |p|
p.selected_barriers.each do |barrier|
Settings.test = barrier
# SelectedBarriers.create(:scenario_response_id => p.id, :barrier => barrier)
end
end
Can anyone please let me know if there's something wrong in my code.
If so how to fix it?
Thanks a lot
I don't think you need to call "each" on p.selected_barriers.Try removing the each and doing this:
Settings.test=p.selected_barriers.
I'm new to RoR too..According to me,the scenario_response is a collection that returns all instances that have the selected_barriers as "". Since you are doing an each on the collection, you will just have one selected_barriers item for each of them.
Please try this and let me know if I'm wrong.
Also you are not doing update_attributes.
Try doing Settings.update_attributes(params[:test]) after Settings.test = barrier .

Associated models and SUM query in Rails

I've got two Rails models, a Child and a Parent say.
I know that I can do this:
Child.sum(:income, :conditions => "parent_id = #{#parent_id}")
But I want to be able to do this:
Parent.children.sum(:income)
But this is giving me the wrong values if I try it. Is there a more concise way of writing
Child.sum(:income, :conditions => "parent_id = #{#parent_id}")
?
TIA
[ps: Rails 3 dev environment]
Sorry but I have just found out the answer to this. I needed to add to_a to the collection of Child objects, and call a proc, as so:
Parent.children.to_a.sum(&:income)
This works a charm.
Sorry for bumping up an old thread, but I think I found better(best?) solution. Below is code for my project that I ended up
self.purchases.where(:script_id => script_id, :approved => true).sum(:instances)
It produces one query that does exactly what I need
SELECT SUM("purchases"."instances") AS sum_id FROM "purchases" WHERE "purchases"."customer_id" = 1 AND "purchases"."script_id" = 1 AND "purchases"."approved" = 't'
I ran into an issue where the child was delegating to the parent and I needed to find a sum.
children.to_a.sum(:parent_income)
was giving me a major N+1 problem. The solution was to use:
children.joins(:parent).sum(:income)