Active Record: AND not working? - ruby-on-rails

I have this Code in Rails 4:
#dominik += Provision.where(teilhaber: 'DW' AND weberkunde: = false).sum(:betrag)*0.9
How can I put this right so that the AND (i mean both conditions shall be true (teilhaber: 'DW' and weberkunde: false) functions correctly.
this does not work either:
#dominik += Provision.where(teilhaber: 'DW').where(weberkunde: = false).sum(:betrag)*0.9 #and weberkunde: false

As you're using a hash
.where(teilhaber: 'DW', weberkunde: false)

Rails has an excellent guide for querying active record:
http://guides.rubyonrails.org/active_record_querying.html
In your case, the syntax for your where query is just a bit off. You have a few different options with the where method.
To use hash conditions:
Provision.where(teilhaber: 'DM', weberkund: false)
Or, you can also use a a SQL-esque syntax.
Provision.where("teilhaber = ? AND weberkund = ?", 'DM', 'false')

Related

Check if a cell in an ActiveRecord Array have been changed

I'm using PostgreSQL which supports arrays, which is very convenient. Sometimes I need to see if an element have been changed.
I know we can do this:
MyActiveRecordArray.changed?
=> true
But is there a way do this:
MyActiveRecordArray[0].changed?
Thank you for your answers and help!
Although you can't do it directly, you may use the changes method:
model = Model.new
model.array_field = [1]
model.changed?
=> true
model.changes['array_field']
=> [[], [1]]
doc: https://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes
Here is the solution I come up with, thanks to your answer
changes_index = []
old_array, new_array = model.changes['array_field']
new_array.each_with_index { |x, i| changes_index << i if x != old_array[i] }
You can ask directly your ActiveRecord instance if a specific attribute has changed by using attribute_name_changed? method.
On your case:
MyModel.active_record_array_changed?
This would return true or false depending whether the specific attribute has changed.

Ruby on Rails: Update Attribute

Google is seriously failing me right now. All I need to do is update one attribute, setting a user to admin, from the Heroku rails console.
I can't find a single simple answer. What I've been trying is:
Record.update_attribute(:roles_mask, "1")
Where record is the correct record.
'undefined method 'update attribute''
I can't just type Record.roles_mask = 1?
EDIT.
I used Record, and I shouldn't have done that in the example. What I've done is exactly this:
ian = User.where(:id => '5')
ian.update_attribute(:roles_mask, '1')
Error: undefined method 'update_attributes'
The problem is that using the .where function creates a relation, rather than finding the record itself. Do this:
ian = User.find(5)
ian.update_attribute(:roles_mask, '1')
Or if you want to use .where then you could do this:
ian = User.where(:id => 5)
ian.first.update_attribute(:roles_mask, '1')
EDIT
See this answer for details about why this is happening.
To use update_attribute (or update_attributes), you need to call that from an instance and not the class.
rails c> rec = Record.find(1)
rails c> rec.update_attribute(:att, 'value')
rails c> rec.update_attributes(att: 'value', att2: 'value2')
I would think that should take care of your issue.
Where clause return a array and you are trying to make update query on array, that's why you got error.
you should try to find out first record
ian = User.where(:id => 1).first
or
ian = User.find(1)
or
ian = User.find_by_id(1)
now your update query will work.
ian.update_attribute(:roles_mask, '1')

Using update_columns in Rails 3?

Is there a shorter way for this in Rails 3?
user.update_column(:attribute1, value1)
user.update_column(:attribute2, value2)
user.update_column(:attribute3, value3)
user.update_column(:attribute4, value4)
I tried update_columns but it's only available in Rails 4.
Thanks for any help.
Here's a workaround for Rails 3.x:
User.where(id: user.id).update_all(attribute1: value1, attribute2: value2, ...)
If you need speed you can also call execute directly on AR connection. I used something like this to import large amount of data.
connection = ActiveRecord::Base.connection
email = connection.quote(email)
zip = connection.quote(zip)
connection.execute(%{UPDATE "users" SET "email" = #{email}, "zip" = #{zip} WHERE "users"."id" = #{user.id}})
Note that validations and callbacks will not be run.
another approach you can take which accomplishes the same thing is this:
user.assign_attributes(
first_name: 'foo',
last_name: 'bar'
)
user.save(validate: false)
NOTE: You don't have to use the validate false. However, the #update_column method does skip validations and callbacks. So if that is what you are looking for, use the validate false.

Rails ternary operator and 'this'

Does Rails have a this like javascript/Jquery does?
Take this example:
User.find_by_email(params[:candidate][:email].present? ? (u = this.id) : (u = 'not here')
or:
if User.find_by_email(params[:candidate][:email].present?
a += 1
user = this
end
I'm aware that this code might be rewritten in more efficient ways in this case, but my question is about being able to use this. Does Ruby have something like this?
In the context of a class you use self.
In these cases though this code is not in User context so you have to make an assignment.
u = User.find_by_email(params[:candidate][:email])
user_name = u.any? ? u.name : 'not here'
I prefer .any? to .present? in this context as it reads better.
Ruby uses self to denote this. I am not quite sure if you need to use self for your problems.
First scenario can be rewritten as:
u = User.find_by_email(params[:candidate][:email]).try(:id) || 'not here'
Second scenario can be rewritten as:
user = User.find_by_email(params[:candidate][:email])
a += 1 if user.present?
I'm guessing the more idiomatic ruby approach for your case would be something like the following:
User.where("email in (?)", email_arr).each do |user|
a += 1
user.foo = bar
end
but it's hard to say without seeing the all code.

Rails 3.1: 'where' with multiple conditions and 'not nil' verification

I want to find records with multiple conditions and this is my code:
#calhappybd = Client.where(:user_id => current_user.id, "birth IS NOT NULL")
I'm trying to do this with squeel-gem, but when I try to use multiple conditions (where{(cond1)(cond2)}), but my current_user.id defined as simple string-data.
With squeel, you should be able to do something like
#calhappybd = Client.where{(user_id == current_user.id) & (birth != nil)}
Let know if you get the same error again...
UPDATED:
Modified the conditions above. Note the single ampersand and double equals. That works for me..
My configuration:
rails 3.1.0.rc6
squeel 0.8.8

Resources