Calling .attributes on model object avoid fileds with nil values - ruby-on-rails

When attributes() is called on a Mongoid model object it excludes the fields with nil values, is there a way to get all the fields irrespective of their values?
media = Media.first
media.attributes #=> ignores nil values
Also, FYI this happens when a record is created with only a few attributes, but when we create a record by assigning nil values to the remaining fields explicitly it works fine!
Any help would be highly appreciated!

mongoid used to remove empty fields. If you kept some fields empty on insert, mongoid will removes them.
Use media.to_json instead for your case.

Related

Undefined method for NilClass in rails console

I've a model named "ListingInfo", whenever I try to generate new object from this model, it shows the "undefined method for nilclass". I'm unable to add its attributes other than id.
I've also tried "create" method but on running "ListingInfo.count.all", it still returns zero(please see second image for more clarity). Means, it is still not being saved to database.
You need to create the object. Using ListingInfo.new will only instantiate it but won't validate it or save it to the DB. Also you shouldn't pass a value on the id that's generated automatically from Rails.
Solutions:
Use new and then save the object
listing = ListingInfo.new
listing.save
Use create
ListingInfo.create
ActiveRecord::Base documentation
create(attributes = nil) {|object| ...}
Creates an object (or multiple objects) and saves it to the database,
if validations pass. The resulting object is returned whether the
object was saved successfully to the database or not.
new(attributes = nil) {|self if block_given?| ...}
New objects can be instantiated as either empty (pass no construction
parameter) or pre-set with attributes but not yet saved (pass a hash
with key names matching the associated table column names). In both
instances, valid attribute keys are determined by the column names of
the associated table — hence you can‘t have attributes that aren‘t
part of the table columns.

Get group by data in rails using psql in rails [duplicate]

I've got a query that does some math and returns a calculated custom select field with the result set. I cannot figure out how to access that in the activerecord object that is returned. I've added an attr_accessor for it also.
attr_accessor :percentage_used
select('gateways.*, (num_transactions_today/ SUM(num_transactions_today)) AS percentage_used ').joins(:gateway_groups).where('map_gateway_groups.gateway_group_id = ?', gateway_group_id)
in the result set, I would expect to have access to :percentage_used, but it is not in there. Any ideas on what i'm doing wrong? i've never needed to do this before.
Thanks
You can access it as
object["percentage_used"]
You neither need nor want attr_accessor for that. attr_accessor creates an instance variable, an accessor method for getting the value of that instance variable, and a mutator method for changing its value. When you say this:
select('gateways.*, (num_transactions_today/ SUM(num_transactions_today)) AS percentage_used ...
ActiveRecord will automatically add a percentage_used method to the returned objects. But the percentage_used method for accessing that value will be added by method_missing. Since you've said attr_accessor :percentage_used, method_missing will never be called and you can't get at the percentage_used value from the query in the usual way.
If you drop the attr_accessor :percentage_used, then you'll be able to call percentage_used on objects returned by that select and you'll find the values you're looking for. However, AR won't be able to convert the value to a native Ruby number though so you'll have to to_f the returned string yourself.

rails 3, how can a reference to fieldname pull data from another source if field is empty?

In my app, users have one "template" record (in Template table) that sets defaults for their data.
Then they create multiple records in (Userdata table).
For each Userdata record, if they enter data into a field, the app uses THAT data (of course). But if Userdata.foo is empty I'd like to use Template.foo instead, transparently. And if both are empty, then it's "empty".
I'm pretty sure the right answer is NOT to code every single place I use every field:
if Userdata.foo.blank?
Template.foo
endif
And I assume it's a matter of somehow defining my model to redefine the fieldname somehow?
And I'm hoping there's some way to not even have to code the model method field-by-field, to basically say "if the field in UserDayta is blank, use the one in Template instead..."
You can define a method in your User model like so:
def fetch_attribute(att)
if self.userdata[att].nil? and self.template[att].nil?
return nil
elsif self.userdata[att].nil?
return self.template[att]
else
return self.userdata[att]
end
end

get current variable Rails, in before_save

Is there a way to get the current variable?
lets say that i have a "title" attribute in a method and i want to check in with the old value of the variable ?
how could i accomplish this ?
ActiveRecord provides a whole set of methods which work on "Dirty" attributes.
In your case, you can call title_was to get the most recently saved version of that variable
If you want to know all the changed attribute and their old values you can use changed_attributes method which will return hash that contains all the changed attribute with their previous values (note that the hash content can be retrieve before saving the new object).
Let assume that you have an object with old_name title:
a = YourModel.where(:title => "old_name")
a.title = "new_title"
a.changed_attributes
Results will be":
{"title"=>"old_name"}
But after saving your changes:
a.save
a.changed_attributes
The results will be empty hash:
{}

Ruby on Rails Array access

My issue involves an array that is apparently not nil but when I try to access it, it is.
The array is returned from a find on an active record. I have confirmed it is in fact an array with the .class method
#show_times = Showing.find_showtimes(params[:id])
#show_times.inspect =>shows that the array is not empty and is a multidimensional array.
#show_times[0] =>is nil
#show_times[1] =>is nil
#show_times.first.inspect => NoMethodError (undefined method `first')
I am perplexed as to why this is..
It's not an array, it's an active record magic structure that mostly looks like an array. I think you can do to_a on it to get a real array, but then a lot of the magic goes away.
find_showtimes is not a built-in finder - if it were, it would return either a single ActiveRecord object or an array of ActiveRecord objects - never a multidimensional array. So the first thing I'd do is have a look a the source of that method.
EDIT: Given your source code (in the comment) - you're actually getting a Hash, not an Array, back from your finder. See the docs for Enumerable's group_by. The Hash is mapping your theater objects to an array of showing objects. This is what you want to do:
Showing.find_showtimes(params[:id]).each do |theater, showtimes|
puts "Theater #{theater} is showing the movie at #{showtimes.join(', ')}"
end
If you're in the console and you want to explore the #show_times object, you can use the keys method to see all the hash keys and then get to individual hash items (such as all the show times) like so:
#show_times[:theater_one]
Same thing will work in your model/view but using each/map/collect would be cleaner as pretty code goes.

Resources