Building and storing complex SQL query for later editing - ruby-on-rails

I am using Rails 3.2.8 to build a "product set" builder that mirrors Google Analytics' Custom Profile builder. For example, a user may define a product set as follows:
(Category = 'Printers') and ((Name contains 'Wireless') or (Name contains 'Wifi'))
My product data is stored in Postgres (9.1.4) using an HStore column to store the dynamic product attributes. I have built a form that can construct the query using Arel but am stuck on the following requirements:
1. The query must be serialized to the database. I can store the .to_sql string but am then stuck with...
2. I must be able to reconstruct the user's form for later editing, as these are not one-time searches but rather shared queries.
How can I serialize in such a way that I can easily reconstruct the user defined query?

Couldn't you just serialize the parameters that rails gets from the form?
You'd have a hash with the keys and values from the user inputted form, and could easily feed it back into whatever logic you use to query the database from said form, or further process it.

You can have persistent model for saving the user's options about the search.
When you need to run the query, you will get the user's saved options and will pass them to custom method that use ransacker. You can access values in the hstore like this:
Arel::Node::InfixOperator.new('->>', 'hstore_column_name', Arel::Nodes::Quoted.new('key_in_hstore'))

Related

Can fields in different but associated tables have the same name is Rails 4

Can fields in different but associated tables have the same names is Rails 4 and be distinct. For example, if I have a class Shipping and a class Receiving, where each has the field EnterTrackingNo, and they are associated via a one to one association on the field shipping_id, will there be any issues with this setup / the fields somehow overlap / interfere with one another?
Thanks
There will not be any issue as Rails will automatically add the table name to the SQL queries it builds when it needs to. You'll be able to access the attribute easily as either shipping.EnterTrackingNo, receiving.EnterTrackingNo, shipping.receiving.EnterTrackingNo, receiving.shipping.EnterTrackingNo, etc. and Rails knows which table you're talking about due to the way they're written.
Even when you search for an object, say you want to search for all Shippings with a Receiving item that has EnterTrackingNo == 3 you'd do
Shipping.includes(:receiving).where(receiving: { EnterTrackingNo: 3 })
The only thing to keep in mind is that if you use SQL fragments (writing a where as a String, for example) you MUST write it as table_name.attribute, otherwise you'll get a SQLException: ambiguous column name. For example:
Shipping.includes(:receiving).where("EnterTrackingNo = 3").references(:receivings)
would not work as Rails, and your DB, have no way of knowing WHICH EnterTrackingNo you're talking about. You'd have to write it as:
Shipping.includes(:receiving).where("receivings.EnterTrackingNo = 3").references(:receivings)
So they know you want the Receiving model's attribute.
You'll also notice I add references(:table_name) to the ones with SQL fragments. This is necesary as well since Rails can't tell it needs a join when you just give it a String.

saving object to database

I have a ruby on rails 4 app and I'm using omniauth-facebook gem for authentication. I have
#omniauth = request.env["omniauth.auth"]
Now I'd like to save a user's education history (#omniauth[:extra][:raw_info][:education]) in the education column of Auth table in the database. #omniauth[:extra][:raw_info][:education] is an Array object which contains OmniAuth::AuthHash objects (i.e. #omniauth[:extra][:raw_info][:education][0].class returns OmniAuth::AuthHash).
Rails api says that "Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method serialize. This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work." So I did the following and it seems to be working:
auth.education = #omniauth[:extra][:raw_info][:education]
auth.save
Is there any downside to this? Is there a better way (like using json, etc)? One downside I can think is that saving data this way makes it difficult for search and query which I probably won't be needing.
Thanks a lot.

Using rails form to populate model with hash

I am currently working on a simple rails4 app. As part of the app, I am creating a form to populate the database and a particular column (:additional), I would like to populate with a hash where the key is a string (heading) and the value an array of strings (paragraphs below heading). So, for example: {"Heading" => ["Paragraph1", "Paragraph2"]} etc.
I am confused how I would now set up a form using rails to populate this column. I was thinking of creating a text_field for the title and then one or more text_areas underneath for the paragraphs and then somehow merging them in the controller but when creating the fields, I have to give the object as :additional which leads to problems.
How would I go about best accomplishing this? Is it even possible or should I restructure my database somehow?
Any advice is much appreciated.
If you're using postgres, ActiveRecord has support for using :hstore as the column type. If you're not, you can use serialize.

how to store in MongoDB in dynamic way without knowing about schema beforehand?

I want to send a very vague and dynamic JSON as a response from a client to server.
for backend I'm using rails + mongoid.
What I know from mongoid is I have to create a model class corresponding to my collection structure so that I can call it from my controller to store data to it this way reminds me traditional RDBMS (still can't figure it out why people are happy with it!!!!)
I don't want to do that , I want to send a JSON (which I don't know about its structure) back to my server and mongoid stores the JSON as it is on the server in other words I don't have any preference structure to storing them and I don't want to have any.
Is there a way to that in rails + mongoid?
Generally Mongoid expects you to specify the fields of your model because there is no underlying schema to infer those fields from in the way that ActiveRecord does. But if you just want to store an arbitrary JSON object you can parse it into a Ruby Hash and store it using Mongoid's hash datatype.
field :untyped_data, type: Hash
There are a few caveats about key names, see http://mongoid.org/en/mongoid/docs/documents.html#fields

Rails. Add a virtual attribute to a User object

I am developing an API in Rails 3. I am fetching users from the database. This works fine but I want to add an "attribute" to the output called Contact_data. This "attribute" or what it is called does not have a counterpart in the database I just need it in the JSON output so that I can add an array to it.
How can this be done?
The current output is: http://pastie.org/1849048. I would like for it to appear for example just below the bio attribute.

Resources