how to differentiate searched or created by first_or_create - ruby

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
...

Related

Mongoid Is it possible to override updated_at timestamp

I am trying to manually edit the "updated_at" field through a rake task
Here is what it looks like:
task :campaigns_updated_at_recovery => :environment do
Dir.foreach('db/raw-data/campaigns/') do |json|
next if json == '.' or json == '..'
file = File.read('db/raw-data/campaigns/'+json)
data_hash = JSON.parse(file)
#p data_hash["_id"]
thisCampaign = Campaign.find(data_hash["_id"])
thisCampaign["channels"].each do |chan|
if chan["updated_at"] < Date.new(2018,04,19)
data_hash["channels"].each do |channel|
if chan["_id"].to_s == channel["_id"]
chan["updated_at"] = Date.parse(channel["updated_at"])
end
end
end
thisCampaign.save
end
end
However when I run this task, the updated_at date is either not changed or updated to today's date.
What am I missing ?
I am using Mongoid and not ActiveRecord by the way
updated_at is updated by mongoid itself in a callback.
You have two solution to work around that.
The easiest solution would be to use set to change the value directly without firing any callback:
thisCampaign.set(channels: thisCampaign['channels'])
The more flexible solution would be to go down to the driver level. The basic idea is:
Campaign.collection.find(_id: data_hash["_id"]).update_one({
'$set' => {
updated_at: yourDate
}
})
Given your example, you would first need to get the full document
thisCampaign = Campaign.collection.find(_id: data_hash["_id"]).first
if thisCampaign
thisCampaign["channels"].each do |chan|
if chan["updated_at"] < Date.new(2018,04,19)
data_hash["channels"].each do |channel|
if chan["_id"].to_s == channel["_id"]
chan["updated_at"] = Date.parse(channel["updated_at"])
end
end
end
end
Campaign.collection.find(_id: data_hash["_id"]).update_one({
'$set' => {channels: thisCampaign["channels"]}
})
end

Ruby DataMapper::ImmutableError

get '/watch/:id' do |id|
#results = Twitchtvst.all( :fields => [:Twitchtv ],
:conditions => { :user_id => "#{id}" }
)
#p #results.inspect
#results.each do |result|
puts result.id
end
erb :mystream
end
I get this error message immutable resource cannot be lazy loaded. How do I fix this?
The Error message is:
DataMapper::ImmutableError at /watch/1
Immutable resource cannot be lazy loaded
According to the official documentation:
Note that if you don't include the primary key in the selected columns, you will not be able to modify the returned resources because DataMapper cannot know how to persist them. DataMapper will raise DataMapper::ImmutableError if you're trying to do so nevertheless.
I know that you are not modifying anything here but I think that the same rule applies for lazy loading. So I will suggest to try it like that:
#results = Twitchtvst.all( :fields => [:Twitchtv, :id],
:conditions => { :user_id => "#{id}" }
) ode here
Note the id as an additional field.

Datamapper into String

I want to be able to see the string like the TwitchTV name I have in my database. Here is my current code
get '/watch/:id' do |id|
erb :mystream
#result = Twitchtvst.all( :fields => [:Twitchtv ],
:conditions => { :user_id => "#{id}" }
)
puts #result
end
result in terminal;
#< Twitchtvst:0x007fb48b4d5a98 >
How do I get that into a string (TwitchTV answer in database)
Opppppsss!
Here is the real code sample. Sorry!
get '/livestream' do
erb :livestream
#users_streams = Twitchtvst.all
puts #users_streams
end
If I add .to_s at users_stream it does not work
By adding .to_csv, not exactly a string, but it should show the content:
get '/livestream' do
erb :livestream
#users_streams = Twitchtvst.all
#users_streams.each do |us|
p us.to_csv
end
end
You're getting a Collection of Twitchtvst objects, so you need to convert each to a String:
puts Twitchtvst.all.map(&:to_s).join

Rho Mobile: Parse and create a model using JSON

I am able to parse a JSON using the following code
$httpresult = #params['body']
$jsonresult = Rho::JSON.parse($httpresult)
But I don't know how to create a model from $jsonresult.
First, using app_info you can print the result coming from the server to check if the response is valid JSON string.
Second, i think you must decode the url in order to parse it by using:
Rho::JSON.parse(Rho::RhoSupport.url_decode(#params['body']))
Once you've the data in json_result, you can put them in a pre-existing Model.
Supposing that you've already created a model with the name "Product", you can use transactions to speed up the process.
At the beginning of your module you've to require the model name:
require_source 'Product'
Then you can do this callback:
def get_callback
if #params['status'] == "ok"
json_result = Rho::JSON.parse(#params['body'])
db = ::Rho::RHO.get_src_db('Product')
db.start_transaction
Product.delete_all
begin
json_result.each do |item|
Product.create({:Brand => item["B rand"], :Name => item["Name"], :SKU => d["SKU"]})
end
db.commit
rescue Exception => e
trace_msg = e.backtrace.join("\n")
puts 'Application initialize failed: ' + e.inspect + ";Trace: #{trace_msg}"
db.rollback
end
WebView.navigate Rho::RhoConfig.start_path
else
WebView.navigate url_for :action => :show_error
end
end

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