In order to work with some client information I have been parsing a 3MB XML file with hpricot... but hpricot takes quite some time to parse the file on a regular basis.
I am thinking about populating this data to a MySql db (once a week) so that I can work with the data directly on mysql with rails.
The file is basically is an XML Google Contacts File that contains client information: Name, email, notes... but also some contact contain multiple value fields such as addresses, telephones.
Currently when I am parsing the data I generate a Contact class
class Contact <
Struct.new(:name, :email, :telephones, :addresses, :user_address,:notes)
end
telephones and addresses contain an array with the different values.
I guess that if I want to recreate this structure in the mysql database I would need to create three tables: contacts, telephones and addresses...
class Contact < ActiveRecord::Base
has_many :addresses
has_many :telephones
end
class Telephone < ActiveRecord::Base
belongs_to :contact
end
class Address < ActiveRecord::Base
belongs_to :contact
end
How would you to populate the Contact class data to the database tables?
Is there a way to insert the data directly from the XML file to the database tables?
Any advice and guidance will be greatly appreciated :)
Thanks!
First why not give nokogiri a try and see if its faster ?
Rails thought people best practices and they came to believe that there is a recipe on how one should program for any given problem. Unfortunately this is not the case, for the usual 90% of tasks there is no magic.
So if you have a contact with some addresses and some telephones it's just that.
Here it's how I would do:
Parse the XML file, if it's too big, stream the parsing.
For each contact in it output a hash just like the params[:contact] would usually turn out in a controller after a form is submitted, and have the Contact model use accepts_nested_attributes_for.
contact = {
:name => xxx,
:user_address => xxx,
:notes => xxx
:addresses_attributes => [
{:some_attribute => xxx, :some_other_attribute => xxx}
...
],
:telephones_attributes => [
{ :some_attribute => xxx, :some_other_attribute => xxx}
...
]
}
Now all that remains is:
Contact.create(contact)
Related
Models structure:-
User has_many :subscriptions
Blog has_one :coupon
Subscription has_one :coupon
I am including the tables
User.includes(subscriptions: :coupon, :blogs)
I am trying to get all users data and only get the valid subscriptions corresponding to it.
If i do
User.includes(subscriptions: :coupon, :blogs).where(:state => 1).references(:subscriptions)
then i am getting the users having only valid subscriptions
So how to get all the users with preloaded blogs coupons and included with valid subscriptions???
If you want to load all users, including those who don't have any valid subscriptions, but for each user be able to access only valid subscriptions, you need to define another association valid_subscriptions. It can be done this way:
In user.rb
has_many :valid_subscriptions, -> { valid }, class_name: 'Subscription'
In subscription.rb, define what being valid means.
scope :valid, -> { where(state: 1) }
Then you query can be User.includes(:blogs, valid_subscriptions: :coupon)
I've been struggling for a while on this (been reading a lot of the ruby on rail guides to try and understand this), but I'm not sure how user inputs work.
I am trying to search for a restaurant in my database with a list of fields the user specifies (cuisine, zipcode, review score). I have created a html.erb page that has the options for all of these.
Here is my controller.
class WelcomeController < ApplicationController
def home
#my_search = Restaurant.joins(:inspection).where(cuisine: c, zipcode: z, totalscore: 1..h)
end
My models for restaurant and inspection also have relations between them (the foreign keys).
How would you go about letting the user give inputs for c (cuisine), z (zipcode) and 1..h (score range)?
I know that people have answered this question in the past, but I think I need a concrete example to actually understand how to do this. As in, what would you put in the html.erb code so that when an option is selected, that value is passed to the method?
Thank you
First you need to create a form in the view. The simplest way to do this is with form_tag:
<%= form_tag(home_path) do %>
<%= text_field_tag 'cuisine' %>
...other inputs
<% end %>
Next, make sure you have a route defined for your controller action in config/routes.rb
post 'home' => 'welcome#home'
Most likely your routes will look different but this is the bare minimum you need.
And in your controller you can access the submitted data using the params object
class WelcomeController < ApplicationController
def home
#restaurants = Restaurant.joins(:inspection).where(
cuisine: params[:cuisine],
# ...other params
)
end
end
I have a Model called Person and Person has multiple posts. When I want to query post count for each person it takes a long time to process since it needs to iterate over each person and query each posts to get the aggregation.
class Person < ActiveRecord::Base
has_many :posts
end
Output (JSON):
Person1
PostsType1Count: 15
PostsType2Count: 45
Person2
PostsType3Count: 33
.
.
.
I want to calculate all the post count for each Person in a optimum way. What would be the best solution?
Here's one way to do this, if you have a small and pre-defined set of Types
class Person < ActiveRecord::Base
has_many :type_1_posts, :class_name => 'Post', :conditions => 'post_type = 1'
has_many :type_2_posts, :class_name => 'Post', :conditions => 'post_type = 2'
has_many :type_3_posts, :class_name => 'Post', :conditions => 'post_type = 3'
end
Then you can write code that looks like this to get all the data:
#all_people = Person.includes(:type_1_posts, :type_2_posts, :type_3_posts).all
The eager loading of the posts allows the count of each type of post to be available, as well as all the posts of each type.
If you need extra performance for this code, because you perform this query a lot, then you can look into using the Rails counter cache mechanism to keep track of the counts of each type on the Person object.
The beauty of Rails here is that your main display code doesn't need to change during this process of making the code faster for reading (adding a counter cache makes adding/deleting posts slower, so you may not want it in all cases).
Write initial code
Use eager loading to make it faster
Use counter cache to make it even faster
Try this May it will work for you
#In Controller
#persons = Person.all
#In View
#persons.each do |person|
person.posts.count # It will gives all posts count
person.posts.collect{|x| true if x.type==1 }.compact.count #If you want to get the post counts based on type
end
Suppose if you want to get any mehods just check in console or debug is person.methods.sort it will give all methods.
try in rails console person.posts.methods also it will give types also then check counts based on type. because i dont know which fields in posts model. so check it.
This is a pretty simple question really, but let's say I'm creating a model for Person. Person obviously has first name, last name, age, etc. But the person also has contact info consisting of things like address line 1, address line 2, city, state, zip, country, phone 1, phone 2, etc...
Does it make more sense to create a model for Person and then list that contact information as tables in the model or to also create, say, a ContactInfo (or Address, etc) model, then associate the Person to ContactInfo through an association (Person has_one ContactInfo/Person has_one Address/Address belongs_to Person, etc)?
Which of these is a better approach and what are the benefits/drawbacks to each method?
edit: in re to j..
So with this approach, would I have to then create an Addressable model?
script/generate model Addressable
class Addressable < ActiveRecord::Base
#stuff here?
end
or is this unnecessary?
Also, would i need to add this line to the create_users.rb:
t.references :addressable, :polymorphic => true
I feel like I'm missing something, but I'm not sure what. I appreciate the help a ton, btw! Thanks!
I'd create separated tables/models for address, phone and stuff like this and would make them polymorphic. Like this:
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
end
class Person < ActiveRecord::Base
has_one :address, :as => :addressable
end
I believe this is the best way because later you may need to add, for example, a Company model and it'll be easy to make it addressable.
Edit
Using the address as example, you'd need an Address model, not Addressable.
And you'll have to add
t.references :addressable, :polymorphic => true
or
t.belongs_to :addressable, :polymorphic => true
to your create_addresses migration, so you'll have the addressable_id and addressable_type in the addresses table.
Let me know if you have any other doubts :]
the answer above makes sense, but think about how many fields you need and how many records you have to manage. creating a table for each additional field may be too much effort.
another approach could be something more flexible: create a table (say, person_details) with 3 fields: person_id:integer, field_name:string, field_data:string, then the model:
class PersonDetail < ActiveRecord::Base
belongs_to :person
end
this way you can add whatever additional field you need: phone1..phoneN, address1..addressN, and so on.
another similar approach is to pre-determine fields names, to avoid different labels during inserts:
class PersonDetail < ActiveRecord::Base
belongs_to :person
FIELD_NAMES => { 'Address' => 1, 'Phone' => 2)
end
in this case you'll declare the field_name as integer (because it stores only the value of the hash, not a string).
I have a large central database of around 1 million heavy records. In my app, for every user I would have a subset of rows from central table, which would be very small (probably 100 records each).When a particular user has logged in , I would want to search on this data set only. Example:
Say I have a central database of all cars in the world. I have a user profile for General Motors(GM) , Ferrari etc. When GM is logged in I just want to search(a full text search and not fire a sql query) for those cars which are manufactured by GM. Also GM may launch/withdraw a model in which case central db would be updated & so would be rowset associated with GM. In case of acquisitions, db of certain profiles may change without launch/removal of new car. So central db wont change then , but rowsets may.
Whats the best way to implement such a design ? These smaller row sets would need to be dynamic depending on user activities.
We are on Rails 2.3.5 and use thinking_sphinx as the connector and Sphinx/MySQL for search and relational associations.
how about using has_many :through
class Manufacturer
class Car
class ManufacturerCarRelation
Manufacturer
has_many :manufacturer_car_relations
has_many :cars through => manufacturer_car_relations
ManufacturerCarRelation
belongs_to :manufacturer
belongs_to :car
Maybe you want to define your index with something like this:
class Car
define_index do
indexes description
has 'cars.manufacturer_id', :as => :manufacturer_id, :type => :integer
end
end
and then use field conditions, like:
Car.search "red", :conditions => {:manufacturer_id => gm.id}
or attribute filters:
Car.search "red", :with => {:manufacturer_id => gm.id}