update_attributes failing when I try to update an attribute - mysql

I have a user database as User(id: integer, username: string, created_at: datetime, updated_at: datetime, password_digest: string, admin: boolean, usermanager: boolean).
I want to update an user and make him Admin, setting the admin varaible to true.
My update in the controller:
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "User edited"
redirect_to current_user
else
render users_url
end
end
The update_attributes is failing in all cases. I opened a debugger and tried to call update_attributes, it is failing there as well.
(byebug) user_params = {"admin"=>true}
{"admin"=>true}
(byebug) #user
#<User id: 1, username: "dsmegha", created_at: "2015-09-11 07:42:01", updated_at: "2015-09-13 03:25:01", password_digest: "$2a$10$BInH6J1dXHanqNIdGag6megSyrmm95AmjTEGPemNdGU...", admin: false, usermanager: nil>
(byebug) #user.update_attributes(user_params)
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE ("users"."username" = 'dsmegha' AND "users"."id" != 1) LIMIT 1
(0.2ms) rollback transaction
false
The update_attribute works for the same.
(byebug) #user.update_attribute(:admin,true)
(0.2ms) begin transaction
(0.1ms) commit transaction
true
(byebug) #user
#<User id: 1, username: "dsmegha", created_at: "2015-09-11 07:42:01", updated_at: "2015-09-13 03:25:01", password_digest: "$2a$10$BInH6J1dXHanqNIdGag6megSyrmm95AmjTEGPemNdGU...", admin: true, usermanager: nil>
(byebug)
Any idea what I am missing here?

Maybe I think current user data is invalid. please check user.errors.
example)
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,:confirmable,
:recoverable, :rememberable, :trackable, :validatable, :lockable
validates :name, presence: true
end
pry
pry(main)> user = User.last
=> #<User:0x007fe328fe56d8
id: 3,
email: "hogehoge#example.com",
name: "",
encrypted_password: "$2a$10$I.xXo0AtAz8nuCUzOGclPe6PA//XMZtjW6fh94D1t25jb7eV9bsS.",
current_sign_in_at: Tue, 02 Jun 2015 01:53:08 JST +09:00,
last_sign_in_at: Tue, 02 Jun 2015 01:52:20 JST +09:00,
current_sign_in_ip: "127.0.0.1",
last_sign_in_ip: "127.0.0.1",
created_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
updated_at: Sun, 13 Sep 2015 13:16:26 JST +09:00,
confirmation_token: nil,
confirmed_at: Tue, 02 Jun 2015 01:52:01 JST +09:00,
confirmation_sent_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
unconfirmed_email: nil,
failed_attempts: 0,
unlock_token: nil,
locked_at: nil,
status: 1>
[7] pry(main)> user.update_attributes(status: 2)
(0.1ms)
BEGIN
(0.2ms)
ROLLBACK
=> false
[8] pry(main)> user.errors
=> #<ActiveModel::Errors:0x007fe328d893f8
#base=
#<User:0x007fe328fe56d8
id: 3,
email: "hogehoge#example.com",
name: "",
encrypted_password: "$2a$10$I.xXo0AtAz8nuCUzOGclPe6PA//XMZtjW6fh94D1t25jb7eV9bsS.",
reset_password_token: "XWmjsEBujb2-aWd5YHYT",
reset_password_sent_at: nil,
remember_created_at: nil,
sign_in_count: 2,
current_sign_in_at: Tue, 02 Jun 2015 01:53:08 JST +09:00,
last_sign_in_at: Tue, 02 Jun 2015 01:52:20 JST +09:00,
current_sign_in_ip: "127.0.0.1",
last_sign_in_ip: "127.0.0.1",
created_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
updated_at: Sun, 13 Sep 2015 13:16:26 JST +09:00,
confirmation_token: nil,
confirmed_at: Tue, 02 Jun 2015 01:52:01 JST +09:00,
confirmation_sent_at: Tue, 02 Jun 2015 01:49:40 JST +09:00,
unconfirmed_email: nil,
failed_attempts: 0,
unlock_token: nil,
locked_at: nil,
status: 2>,
#messages={:name=>["can't be blank"]}>
additionally write.
View has password input field perhaps? In that case, I think you need to delete passward params when update user data.
How about this?
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,:confirmable,
:recoverable, :rememberable, :trackable, :validatable, :lockable
validates :name, presence: true
def update_without_current_password(params, *options)
params.delete(:current_password)
if params[:password].blank?
params.delete(:password)
params.delete(:password_confirmation) if params[:password_confirmation].blank?
end
clean_up_passwords
update_attributes(params, *options)
end
end
controller
def update
#user = User.find(params[:id])
if #user.update_without_current_password(user_params)
flash[:success] = "User edited"
redirect_to current_user
else
render users_url
end
end

Related

How to fetch objects in joins?

This is my schema :
Mention.rb
belongs_to :user
create_table "mentions", force: :cascade do |t|
t.integer "user_id", limit: 4
t.integer "mentionable_id", limit: 4
t.string "mentionable_type", limit: 191
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "deleted_at"
end
User.rb
No Association.
Query:
mentions = Mention.joins(:user).where(mentions: {mentionable_type: 'Comment', mentionable_id: #comments_ids}).select('users.*, mentions.mentionable_id AS comment_id').group_by(&:comment_id)
Output :
=> {155=>
[#<Mention:0x00007ff51a309de8 id: 110, created_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, updated_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, deleted_at: nil>,
#<Mention:0x00007ff51a3092f8 id: 112, created_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, updated_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, deleted_at: nil>],
156=>[#<Mention:0x00007ff51a3098e8 id: 111, created_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, updated_at: Thu, 07 Nov 2019 10:19:46 UTC +00:00, deleted_at: nil>]}
id:110 that is here in the output is of user and 115 is mentionable_id.
How can I get complete user object with group_by mentionable_id ?
Expected:
=> {155=>
[#<User:0x00007ff51a309de8 id: 110, name: "abc", email: 'xyz#mail.com', deleted_at: nil>,
#<User:0x00007ff51a3092f8 id: 112, name: "abc", email: 'xyz#mail.com', deleted_at: nil>],
156=>[#<User:0x00007ff51a3098e8 id: 111, name: "abc", email: 'xyz#mail.com', deleted_at: nil>]}
You need to query through User:
User.joins(:mentions)
.where(mentions: { mentionable_type: 'Comment', mentionable_id: #comments_ids })
.select('users.*, mentions.mentionable_id AS comment_id')
.group_by(&:comment_id)

Selecting all the records from table to which given number belongs to

Suppose I have following three records in my model :
#<Rda:0xf6e8a0c
id: 1,
age_group: "18-100",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
#<Rda:0xf6e8a0c
id: 2,
age_group: "10-15",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
#<Rda:0xf6e8a0c
id: 3,
age_group: "20-100",
weight: "60",
nutrient: "energy(kcal/day)",
value: "2730",
created_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00,
updated_at: Sat, 15 Oct 2016 08:21:43 UTC +00:00>
Now, I want to get all those records in which my given value falls in a 'age_group' columns ranges. For example: suppose my age is 25 then I should get records with ids 1 & 3 from the above records because '25' falls in between '18-100' and '20-100'
You might do
def self.foo(age)
all.select { |rda| Range.new(*rda.age_group.split('-').map(&:to_i)).cover? age }
end

How to give a date of start for users on Freeradius

I want to be able to delay the activation of the login. For example i can create an user monday, but i just want allow him to connect only from friday to logon on my network.
So i created an attribute on the file dictionary.conf
ATTRIBUTE Acc-start-date 3003 date
This attribute is used in the databse sql like an attribute
And in the /site-available/default in the authorise section
if (Acc-Start-Date < "%{Current-Time}") {
reject
}
But I get an error,
rad_recv: Access-Request packet from host 127.0.0.1 port 58341, id=131, length=277
ChilliSpot-Version = "1.3.0"
User-Name = "date"
User-Password = "date"
Service-Type = Login-User
Acct-Session-Id = "556ea52d00000004"
Framed-IP-Address = 10.10.4.200
NAS-Port-Type = Wireless-802.11
NAS-Port = 4
NAS-Port-Id = "00000004"
Calling-Station-Id = "00-1B-77-16-34-1A"
Called-Station-Id = "00-50-56-B2-BF-8D"
NAS-IP-Address = 10.10.4.254
NAS-Identifier = "vlan4"
WISPr-Location-ID = "isocc=,cc=,ac=,network=Coova,Vlan4_ssid"
WISPr-Location-Name = "Vlan_4"
WISPr-Logoff-URL = "http://10.10.4.254:3990/logoff"
Message-Authenticator = 0x96a538a9ed829e695c3d62f22e5d1962
Wed Jun 3 08:57:48 2015 : Info: # Executing section authorize from file /etc/freeradius/sites-enabled/default
Wed Jun 3 08:57:48 2015 : Info: +- entering group authorize {...}
Wed Jun 3 08:57:48 2015 : Info: ++? if (!NAS-IP-Address)
Wed Jun 3 08:57:48 2015 : Info: ? Evaluating !(NAS-IP-Address) -> FALSE
Wed Jun 3 08:57:48 2015 : Info: ++? if (!NAS-IP-Address) -> FALSE
Wed Jun 3 08:57:48 2015 : Info: ++[preprocess] returns ok
Wed Jun 3 08:57:48 2015 : Info: ++[chap] returns noop
Wed Jun 3 08:57:48 2015 : Info: ++[mschap] returns noop
Wed Jun 3 08:57:48 2015 : Info: ++[digest] returns noop
Wed Jun 3 08:57:48 2015 : Info: [suffix] No '#' in User-Name = "date", looking up realm NULL
Wed Jun 3 08:57:48 2015 : Info: [suffix] No such realm "NULL"
Wed Jun 3 08:57:48 2015 : Info: ++[suffix] returns noop
Wed Jun 3 08:57:48 2015 : Info: [eap] No EAP-Message, not doing EAP
Wed Jun 3 08:57:48 2015 : Info: ++[eap] returns noop
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: %{User-Name} -> date
Wed Jun 3 08:57:48 2015 : Info: [sql] sql_set_user escaped user --> 'date'
Wed Jun 3 08:57:48 2015 : Debug: rlm_sql (sql): Reserving sql socket id: 3
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'date' ORDER BY id
Wed Jun 3 08:57:48 2015 : Info: [sql] User found in radcheck table
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radreply WHERE username = 'date' ORDER BY id
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: SELECT groupname FROM usergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM usergroup WHERE username = 'date' ORDER BY priority
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = 'date_check' ORDER BY id
Wed Jun 3 08:57:48 2015 : Info: [sql] User found in group date_check
Wed Jun 3 08:57:48 2015 : Info: [sql] expand: SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = 'date_check' ORDER BY id
Wed Jun 3 08:57:48 2015 : Debug: rlm_sql (sql): Released sql socket id: 3
Wed Jun 3 08:57:48 2015 : Info: ++[sql] returns ok
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Entering module authorize code
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Could not find Check item value pair
Wed Jun 3 08:57:48 2015 : Info: ++[chillispot_max_bytes] returns noop
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Entering module authorize code
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Could not find Check item value pair
Wed Jun 3 08:57:48 2015 : Info: ++[noresetcounter] returns noop
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Entering module authorize code
Wed Jun 3 08:57:48 2015 : Debug: rlm_sqlcounter: Could not find Check item value pair
Wed Jun 3 08:57:48 2015 : Info: ++[dailycounter] returns noop
Wed Jun 3 08:57:48 2015 : Info: ++? if (Acc-Start-Date < "%{Current-Time}")
Wed Jun 3 08:57:48 2015 : Info: expand: %{Current-Time} ->
Wed Jun 3 08:57:48 2015 : Info: (Attribute Acc-Start-Date was not found)
Wed Jun 3 08:57:48 2015 : Info: ? Evaluating (Acc-Start-Date < "%{Current-Time}") -> FALSE
Wed Jun 3 08:57:48 2015 : Info: ++? if (Acc-Start-Date < "%{Current-Time}") -> FALSE
Wed Jun 3 08:57:48 2015 : Info: ++[expiration] returns noop
Wed Jun 3 08:57:48 2015 : Info: ++[logintime] returns noop
Wed Jun 3 08:57:48 2015 : Info: ++[pap] returns updated
My freeradius can't find my attribut, should I write somewhere the query sql to find this attribute ?
You might want to add this in your policy.conf and not default
if (Acc-start-date < "%{Current-Time}") {
reject
}

Searching through databases serialized column

In MySQL Rails 3 application, one of my columns are serialized to Hash. My question is simple: how can I get results based on this column?
I tried this approach:
example_hash = {id: 666}
ExampleTable.last.hash == example_hash
:true ###### Here you can see that both hashes are the same
Still, a query like this give me no results and no exceptions:
ExampleTable.where('hash LIKE ?', example_hash)
It just doesn't detect the record I need.
my_hash = {id:666}
search_term = my_hash.serializable_hash
ExampleTable.where(search_term)
I tried this in an existing Rails 4 app. You will have to test if it works in Rails 3. I don't have include ActiveModel::Serialization in my model and it still works.
Here is my console session:
Loading development environment (Rails 4.0.0)
$pry(main)> t = Tool.first
Tool Load (10.9ms) SELECT "tools".* FROM "tools" ORDER BY "tools"."id" ASC LIMIT 1
=> #<Tool id: 2, name: "6", serial: "134989652", purchased: nil, put_in_service: nil, cost: nil, value: nil, in_service: true, retired: nil, created_at: "2013-07-17 06:12:59", updated_at: "2014-02-13 17:19:10", note: "", condition: "5 - Brand New Condition", old_location: "Sta 75", model: "Stihl 066", loaner: false, location_id: 9, category_id: 2, annual_service: false>
$pry(main)> x = t.serializable_hash
=> {"id"=>2,
"name"=>"6",
"serial"=>"134989652",
"purchased"=>nil,
"put_in_service"=>nil,
"cost"=>nil,
"value"=>nil,
"in_service"=>true,
"retired"=>nil,
"created_at"=>Tue, 16 Jul 2013 23:12:59 PDT -07:00,
"updated_at"=>Thu, 13 Feb 2014 09:19:10 PST -08:00,
"note"=>"",
"condition"=>"5 - Brand New Condition",
"old_location"=>"Sta 75",
"model"=>"Stihl 066",
"loaner"=>false,
"location_id"=>9,
"category_id"=>2,
"annual_service"=>false}
$pry(main)> Tool.where(x)
Tool Load (10.3ms) SELECT "tools".* FROM "tools" WHERE "tools"."id" = 2 AND "tools"."name" = '6' AND "tools"."serial" = '134989652' AND "tools"."purchased" IS NULL AND "tools"."put_in_service" IS NULL AND "tools"."cost" IS NULL AND "tools"."value" IS NULL AND "tools"."in_service" = 't' AND "tools"."retired" IS NULL AND "tools"."created_at" = '2013-07-17 06:12:59.638381' AND "tools"."updated_at" = '2014-02-13 17:19:10.674233' AND "tools"."note" = '' AND "tools"."condition" = '5 - Brand New Condition' AND "tools"."old_location" = 'Sta 75' AND "tools"."model" = 'Stihl 066' AND "tools"."loaner" = 'f' AND "tools"."location_id" = 9 AND "tools"."category_id" = 2 AND "tools"."annual_service" = 'f'
=> [#<Tool id: 2, name: "6", serial: "134989652", purchased: nil, put_in_service: nil, cost: nil, value: nil, in_service: true, retired: nil, created_at: "2013-07-17 06:12:59", updated_at: "2014-02-13 17:19:10", note: "", condition: "5 - Brand New Condition", old_location: "Sta 75", model: "Stihl 066", loaner: false, location_id: 9, category_id: 2, annual_service: false>]

Query for distinct instance of model + one other field

I have a model called Evaluation. When an evaluation is created, an eval_number is created with it. There are many evaluations with the same eval_number.
Here's an example:
- !ruby/object:Evaluation
attributes:
id: 2023
score: 3
created_at: 2013-09-08 13:10:53.000000000 Z
updated_at: 2013-09-08 13:10:53.000000000 Z
student_id: 26
goal_id: 50
eval_number: 33
- !ruby/object:Evaluation
attributes:
id: 2099
score: 4
created_at: 2013-09-08 13:19:12.000000000 Z
updated_at: 2013-09-08 13:19:12.000000000 Z
student_id: 26
goal_id: 36
eval_number: 34
- !ruby/object:Evaluation
attributes:
id: 2100
score: 3
created_at: 2013-09-08 13:19:12.000000000 Z
updated_at: 2013-09-08 13:19:12.000000000 Z
student_id: 26
goal_id: 37
eval_number: 34
- !ruby/object:Evaluation
attributes:
id: 2101
score: 4
created_at: 2013-09-08 13:19:12.000000000 Z
updated_at: 2013-09-08 13:19:12.000000000 Z
student_id: 26
goal_id: 38
eval_number: 34
In a view, I want to show the date that a given evaluation was created in a table header. It should look like this:
date_1 | date_2 | date_3 | date_4 | etc..
To do this, I need to get distinct evaluation_numbers + the created_at dates that go with them. I thought that this would help, but it's returning more than one record per eval_number with this code:
def eval_date(i)
evals = self.goals.first.evaluations
eval = evals.select("distinct(eval_number), created_at").all[i]
eval.created_at.to_date
end
It seems like distinct eval_numbers are being selected, but also distinct created_at columns (which of course are all different). This makes the .all[i] basically useless as it's finding the [0], [1], [2], etc element correctly - but there are far more than whatever the given number of i is in the returned array.
I want to find a distinct eval_number and load only the created_date that goes with it. I think I could load the whole record with all attributes, but I don't need them, so I'd rather not.
Try this:
def eval_date(i)
evals = self.goals.first.evaluations
eval = evals.order("eval_number").group(:eval_number).all[i]
eval.created_at.to_date
end
PS: if you are calling eval_date repeatedly then cache the evaluations like so
def eval_date(i)
#evals ||= self.goals.first.evaluations.order("eval_number").group("eval_number").all
eval = #evals[i]
eval.created_at.to_date
end
got it working like this, but i'm open to better suggestions:
#student.rb
def eval_date(i)
eval = self.goals.first.evals_by_number.values[i].first
eval.created_at.strftime("%d %b, %Y")
end
#goal.rb
def evals_by_number
self.evaluations.order("eval_number").group_by(&:eval_number)
end