Get records by hash value - sql

I'm trying to get records from table by hash value.
Here is record example:
Activity:0x0000000709be18> {
:id => 1,
:trackable_id => 3,
:trackable_type => "User",
:owner_id => 1,
:owner_type => "User",
:key => "user.ban",
:parameters => {
:status => "new"
},
:recipient_id => nil,
:recipient_type => nil,
:created_at => Wed, 01 Jun 2016 22:19:39 UTC +00:00,
:updated_at => Wed, 01 Jun 2016 22:19:39 UTC +00:00
}
I need to get all Activities with paremeters status new (parameters[:status] == 'new').
This code works, but I need to return activerecord relation not an array.
Activity.select{|act| act.parameters == { status: 'new'}}

It is not easy to search within a serialized field, but you can use LIKE with some limitations.
Activity.where('parameters LIKE ?', '%status: new%')
This is working, but I do suggest adding a custom field, just like what public activity gem owner has mentioned:
"Besides the few fields that every activity has, you can also set
custom fields. This could be very beneficial, as parameters are a
serialized hash, which cannot be queried easily from the database."

Related

Rails 3: Delete association duplicates from the database

I've got these models:
class Relationship < ActiveRecord::Base
belongs_to :student
belongs_to :guardian
end
class Student < ActiveRecord::Base
has_many :relationships
has_many :guardians, through: :relationships
end
class Guardian < ActiveRecord::Base
has_many :relationships
has_many :students, through: :relationships
end
I don't want any guardian to be related many times with one student. This can be prevented with a validation, but let's say it's too late and there are case where this is happening. For example, where g is a guardian:
g.relationships
[
[0] #<Relationship:0x0000000bc33650> {
:id => 40321,
:relationship_type_id => 2,
:student_id => 41700,
:guardian_id => 45820,
:created_at => Tue, 23 Apr 2013 17:44:29 UTC +00:00,
:updated_at => Tue, 23 Apr 2013 17:44:29 UTC +00:00,
},
[1] #<Relationship:0x0000000bc32e80> {
:id => 40923,
:relationship_type_id => 2,
:student_id => 41700,
:guardian_id => 45820,
:created_at => Tue, 23 Apr 2013 18:58:46 UTC +00:00,
:updated_at => Tue, 23 Apr 2013 18:58:46 UTC +00:00,
}
]
As you can see, these two relationships share the same student_id. I want to find out if there's a way I can delete from the database the duplicated relationships. I've tried the following lines of code to no avail:
g.relationships.uniq!(&:student_id)
g.update_attributes(relatioships: g.relationships.uniq!(&:student_id))
How can I solve this problem. Thanks!
subquery = Relationship.select("student_id, guardian_id").
group(:student_id, :guardian_id).
having("count(*) > 1").to_sql
groups = Relationship.joins("JOIN (#{subquery}) sub ON relationships.student_id = sub.student_id AND relationships.guardian_id = sub.guardian_id").
group_by{|r| [r.student_id, r.guardian_id] }
groups.values.each do |duplicates|
duplicates.drop(1).each(&:destroy)
end

Parse embedded string form JSON

I have a Rails 3 application and I am using the following code to parse a JSON post:
email_payload = JSON.parse(params[:payload])
Result.create(:from => email_payload['from'], :from_name => email_payload['from_name'], :from_address => email_payload['from_address'], :date => email_payload['date'], :html_body => email_payload['html_body'], :priority => email_payload['priority'], :spam_status => email_payload['spam_status'], :subject => email_payload['subject'])
The JSON post data is as follows:
payload{ "address_identifier": null, "attachments": [ [ "twitter.png", "image/png", 3029, "http://api.deliverhq.com/api/incoming/attachment/7gdd71wo75/5772412/0" ] ], "cc": null, "date": "Thu, 25 Oct 2012 22:04:20 +0100"
I am trying to work out how to parse the URL, in this case http://api.deliverhq.com/api/incoming/attachment/7gdd71wo75/5772412/0, and then enter the URL into the database.
:url => email_payload['attachments']
won't work because there is multiple values within attachment and:
email_attachments_payload = JSON.parse(params[:payload][:attachments])
:url => email_attachments_payload['URL']
won't work because the URL doesn't have an identifier. For this particular application there should only ever be one attachment, therefore selecting .first may be an option if that's possible.
Any pointers would be appreciated!
UPDATE:
Adding:
email_payload[:attachments][0][4]
results in the following exception error:
NoMethodError: undefined method []' for nil:NilClass
UPDATE 2
def receive_fax
if request.get?
render :text => "hello"
elsif request.post?
email_payload = JSON.parse(params[:payload])
Fax.create(:from => email_payload['from'], :from_name => email_payload['from_name'], :from_address => email_payload['from_address'], :date => email_payload['date'], :html_body => email_payload['html_body'], :priority => email_payload['priority'], :spam_status => email_payload['spam_status'], :subject => email_payload['subject'], :fax => email_payload[:attachments][0][3])
render :text => "success"
else
render :text => "error"
end
end
In irb:
require 'json'
email_payload = JSON.parse('{ "address_identifier": null, "attachments": [ [ "twitter.png", "image/png", 3029, "http://api.deliverhq.com/api/incoming/attachment/7gdd71wo75/5772412/0" ] ], "cc": null, "date": "Thu, 25 Oct 2012 22:04:20 +0100" }')
#=> {"address_identifier"=>nil, "attachments"=>[["twitter.png", "image/png", 3029, "http://api.deliverhq.com/api/incoming/attachment/7gdd71wo75/5772412/0"]], "cc"=>nil, "date"=>"Thu, 25 Oct 2012 22:04:20 +0100"}
email_payload['attachments'][0][3]
#=> "http://api.deliverhq.com/api/incoming/attachment/7gdd71wo75/5772412/0"
If that doesn't work then there's something else going on that you haven't described above.
UPDATE: in the hash returned from JSON.parse, the attachments key should be a string ('attachments'), not a symbol (:attachments). Updated my answer above.
Please try: email_payload['attachments'][0][3]
It appears that the problem may be the difference between :attachments (a symbol) and 'attachments' (a string).

Differences in expires_in cookies in Rails

What is the difference between:
cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
and
cookies[:login] = { :value => "XJ-122", :expires => 1.hour }
Aren't both times calculated at the time the cookie is set, and therefore 'from_now' is irrelevant?
You can always check your understanding using "rails console".
$ rails c
Loading development environment (Rails 3.2.3)
1.9.2-p318 :001 > 1.hour
=> 3600 seconds
1.9.2-p318 :002 > 1.hour.class
=> Fixnum
1.9.2-p318 :003 > 1.hour.from_now
=> Fri, 25 May 2012 04:16:57 UTC +00:00
1.9.2-p318 :004 > 1.hour.from_now.class
=> ActiveSupport::TimeWithZone
ActiveSupport::TimeWithZone is a 'glorified' Time class.
:expires needs a Time instance. So, you should use 1.hour.from_now

Rails 3.1 postgresql shooting blanks into db

I'm using postgresql in development for the first time and have successfully installed the binary onto my 10.6 machine. I've created a Rails superuser, createdb => 'vitae_development' with this user. It shows up in $pqsl => '/du', but when I key in /dt, I get 'no relations'.
My pg gem is pg-0.12.0
In rails 3.10 console, I enter: User.create!(:name => "Sam", :email => "sam#email.me")
The resulting output is:
INSERT INTO "users" ("created_at", "email", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Wed, 21 Dec 2011 19:40:13 UTC +00:00], ["email", nil], ["name", nil], ["updated_at", Wed, 21 Dec 2011 19:40:13 UTC +00:00]]
That appears to be a bunch of blanks. I've searched the googles but must have missed the right search terms.
pgAdmin3 seems to show the tables in place, as best as I can determine, but with no data that I can find.
This is the relevant snippet from my database.yml:
development:
adapter: postgresql
database: vitae_development
username: rails
password:
pool: 5
timeout: 5000
For completeness, here's the whole user.rb:
class User < ActiveRecord::Base
attr_accessor :name, :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_insensitive => false }
end
What am I overlooking? I've done rake db:migrate.
Did you perhaps override the email or email= methods or put attr_accessor :email in your User.rb file?
EDIT:
Take out line 2 where it says attr_accessor :name, :email. attr_accessor in the context of rails is for object variables that won't be saved to the database.
Try eliminating the formatting validation on email...if it works I'd take a deeper look at email_regex

Rails date being changed by model

I have a form with a date select.
I have the following form:
<%= date_select :user, :birthday, {:start_year => Time.now.year, :end_year => 1910,:order => [:day,:month,:year], :prompt => { :day => 'day', :month => 'month', :year => 'year' }}, { :class => "default" } %>
Validation in my model:
validates :birthday, :if => :should_validate_birthday?,
:presence => {:message => "Please enter your friend's birthdate"},
:date => { :after => Date.civil(1910,1,1), :before => Date.today, :message => "Please enter a valid date"}
Here is an example of what the user submits in the log:
"user"=>{"name"=>"rewrwe", "birthday(3i)"=>"1", "birthday(2i)"=>"", "birthday(1i)"=>"2008", "email"=>""}}
NOTE that the value for the month is blank.
IN the controller I create the user
create
#user = User.new(params[:user])
If #user.save
#go to the confirm page
end
end
No error messages are shown even though the month is missing because for some reason when I try to save the model it converts an empty month to "January" or 01.
This is very frustrating as I don't want users to submit bad data by accident.
How can I stop Rails from doing this and make sure all the date information is submitted?
Separate the three fields with attr_accessor:
class User < ActiveRecord::Base
attr_accessor :birthday_year, :birthday_month, :birthday_date
validates_presence_of :birthday_year, :birthday_month, :birthday_date
# ...
end
And then in your view just have different selects for each of them. That's all the date_select does but it splits them up in the view, rather than in the model, which makes it hard to validate each field.