What is that :name syntax? - typeorm

In TypeORM documentation, there are examples like this:
import {getConnection} from "typeorm";
await getConnection()
.createQueryBuilder()
.update(User)
.set({ firstName: "Timber", lastName: "Saw" })
.where("id = :id", { id: 1 })
.execute();
Where can I find more information on that :id syntax? Can it be used in the .set method also?

That's a query parameter: https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#using-parameters-to-escape-data
I don't think it makes sense to use it in the set-method, since you are passing an object there, which should already be escaped. Query parameters are used to make queries more readable and to prevent SQL injections.

Related

Rails how to censor some parameters from logs

I'm doing some custom logging in my Rails application and I want to automatically sensor some parameters. I know that we have fitler_parameter_logging.rb which does this for the params object. How can I achieve something like this for my custom hash.
Let's say I'm logging something like this:
Rails.logger.info {name: 'me', secret: '1231234'}.inspect
So my secret key should be sensored in the logs.
I know I can personally delete the key before logging, but it adds noise to my application.
The question title talks about removing the parameters, but your question refers to censoring the parameters similar to how Rails.application.config.filter_parameters works. If it's the latter, it looks like that's already been answered in Manually filter parameters in Rails. If it's the former, assuming a filter list, and a hash:
FILTER_LIST = [:password, :secret]
hash = {'password' => 123, :secret => 321, :ok => "this isn't going anywhere"}
then you could do this:
hash.reject { |k,v| FILTER_LIST.include?(k.to_sym) }
That'll cope with both string and symbol key matching, assuming the filter list is always symbols. Additionally, you could always use the same list as config.filter_parameters if they are going to be the same and you don't need a separate filter list:
hash.reject { |k,v| Rails.application.config.filter_parameters.include?(k.to_sym) }
And if you wanted to make this easier to use within your own logging, you could consider monkey patching the Hash class:
class Hash
def filter_like_parameters
self.reject { |k,v| Rails.application.config.filter_parameters.include?(k.to_sym) }
end
end
Then your logging code would become:
Rails.logger.info {name: 'me', secret: '1231234'}.filter_like_parameters.inspect
If you do monkey patch custom functionality to core classes like that though for calls you're going to be making a lot, it's always best to use a quite obtuse method name to reduce the likelihood of a clash with any other library that might share the same method names.
Hope that helps!

How to create a new record using the values from a variable already under the same class

I remove records all the time to test, and need to re-create the same record to test again.
So doing this:
User.create(name: "Peter", col1: "etc", col2: "etc", ...)
u = User.last
User.last.delete
How to accomplish something like this?:
User.create(u)
u is already an instance of User class`:
u.class => User(id: integer, name: string, ...)
How to accomplish something like this?:
User.create(u)
create accepts the hash, so you can pass the hash key-value pairs of all u attributes (except for id):
User.create(u.attributes.except('id'))
Note, that it will fail if you have any uniqueness validation.
Turned out to be as simple as:
User.create!(u.attributes)
if you use this :
User.create!(u.attributes)
it will give you error ' ActiveRecord::RecordNotUnique '
You can use this. It will create new record with new id
User.create(u.attributes.except('id'))

ruby: wrap each element of an array in additional quotes

I have a following string :
a = "001;Barbara;122"
I split in into array of strings:
names = a.split(";")
names = ["001", "Barbara", "122"]
What should I do to have each element wrapped additionally in '' quotes?
The result should be
names = ["'001'", "'Barbara'", "'122'"]
I know it sounds strange but I need it for database query in ruby on rails. For some reason I cannot access database record if my name is in "" quotes. I do have mk1==0006 in the database but rails does not want to access it somehow. However, it does access 1222.
sql = "SELECT mk1, mk2, pk1, pk2, pk3, value_string, value_number FROM infos WHERE mk1 in (0006) AND value_string ='männlich';"
recs = ClinicdbInfo.find_by_sql(sql)
=> []
sql = "SELECT mk1, mk2, pk1, pk2, pk3, value_string, value_number FROM infos WHERE mk1 in (1222) AND value_string ='männlich';"
recs = ClinicdbInfo.find_by_sql(sql)
=> [#<Info mk1: "1222", mk2: "", pk1: "Information allgemein", pk2: "Geschlecht", pk3: "Wert", value_string: "männlich", value_number: nil>]
So, I just need to wrap every element of names into additional ''-quotes.
names.map{ |e| "'" + e + "'" }
=> ["'001'", "'Barbara'", "'122'"]
or
names.map{ |e| "'#{e}'" }
=> ["'001'", "'Barbara'", "'122'"]
You should not concatenate parameters to sql string manually; you should instead pass parameters into find_by_sql method. Example:
sql = "SELECT mk1, mk2, pk1, pk2, pk3, value_string, value_number FROM infos WHERE mk1 in (?) AND value_string = ?"
recs = ClinicdbInfo.find_by_sql [sql, 1222, "männlich"]
This way the necessary type conversions and escaping to prevent against sql injection will be handled by Rails.
I agree with #jesenko that you should not construct your SQL queries and let AR do the type conversion and escape input against SQL injection attacts. However, there are other use cases when you'd want this. For example, when you want to insert an array of strings into your js. I prefer using the following syntax for those rare cases:
names.map &:inspect # => ["\"001\"", "\"Barbara\"", "\"122\""]
If you are print this in your views, you should mark it as html safe:
names.map(&:inspect).html_safe

Rails + Postgres JSON fields and update_column

I've been playing around Rails (4) + Postgres JSON fields a bit now, and I've noticed that if I do something like this
model.json_data = {
field1: "hello",
field2: "world"
}
model.save
it works fine. However if I do
model.update_column(:json_data, {
field1: "hello",
field2: "world"
} )
it doesn't work. It doesn't seem like update_column is storing the data as JSON, but just a string with line breaks and tabs included. The problem is, I want the json_data to be generated in an after_save callback, so I need to not re-trigger the after_save callback when updating the JSON field.
Any thoughts on what might be going on here, or how to get around it?
Nevermind, I found a solution.
model.update_column(:json_data, {
field1: "hello",
field2: "world"
}.to_json )
Seems obvious in hindsight.

Ruby on Rails ActiveRecord find_by-sql field names

I'm doing custom find_by_sql queries which are dynamically created by user input. What is the best way to find the field names returned by find_by_sql
I've tried using columns, column_names and keys methods but none work.
Is the ActiveRecord result a hash or an array?
e.g.
#fm_reports = FmReport.find_by_sql(crosstab_query)
field_names = #fm_reports.keys (or .columns or .column_names)
Cheers, Keith
Update ::
It seems that unless you do "select * from ...." in a find_by_sql it does not return the attribute names
>> FmReport.find_by_sql("select object_class, alarm_mr from fm_reports limit 1")
=> [#<FmReport >]
>> FmReport.find_by_sql("select * from fm_reports limit 1")
=> [#<FmReport id: 7, ALARM_DN: "PLMN-PLMN/BSC-31569/TCSM-72", ALARM_OBJECT: "MELB_BSC1", ALARM_MR: "VIC_METRO", PARENT_DN: "PLMN-PLMN/BSC-31569", PARENT_CLASS: "BSC", OBJECT_CLASS: "TCSM", ALARM_NUMBER: "2955", ALARM_TIME: "21/12/2009 11:02:19", CANCEL_TIME: "21/12/2009 11:03:27", SEVERITY: "2", created_at: nil, updated_at: nil>]
#fm_reports = FmReport.find_by_sql(crosstab_query)
field_values = #fm_reports.attributes
field_values.each {|key, value| puts key}
The above line will return a hashmap of field-names and their values. They can be iterated on if req.
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002353
attribute_names
Maybe you're looking for #attributes?
Also, find_by_sql returns an Array so that's why there's no method called attributes. How about doing first.attributes on the result of your find?
Another question is why are you using find_by_sql at all?
Why not just use ActiveRecord's built in stuff for this?
SomeModel.find( :all, :limit => 1 ).first.attributes
I know this is old, but it might help anyone with the same question.
I usually do it like this:
#fm_reports = FmReport.find_by_sql(crosstab_query)
field_names = #fm_reports.first.attributes.keys

Resources