Jacob Montgomery

Joined

34,480 Experience
33 Lessons Completed
41 Questions Solved

Activity

Posted in A `has_one :through` association issue

Hey Jack, your associations should fit how you plan on querying and manipulating the data, not necessarily how your users interact with it or from one particular perspective. So the way I kind of look at it is you have 2 main components to a website - a frontend and a backend. Your frontend should be concerned with how your users interact with data on your site (UX) - and the backend should be concerned with how your server interacts with the data. This ensures that your users can use your site as effeciently as possible, and your application can run on your server as efficiently as possible. Your controllers and helpers get to then be the middleman that helps the two ideas communicate correct. Check out http://stackoverflow.com/questions/2116017/rails-has-one-through-association to get an idea of what I mean.

Regarding the account model, off the top of my head I believe I would adjust my models to be like this:

#seller.rb
has_many :receipts
has_many :companies, :through => :receipts
# no foreign_keys here

#company.rb
has_many :receipts
has_many :sellers, :through => :receipts
has_one :account
# no foreign_keys here

#receipt.rb
belongs_to :company
belongs_to :seller
# need company_id, account_id, seller_id fields here

#account.rb
has_one :company
has_many :receipts, :through => company
# need company_id here

This should let you then query Account.first.receipts to display all the receipts for that account and there wouldn't be any duplication of any records. You'd also get Company.first.account and Receipt.first.account You'll want to make sure you have the proper foreign_keys setup. I included a comment under each model for the keys that should be all you need.

Posted in A `has_one :through` association issue

Huh, weird - get an error when trying to update posts and then when the page refreshed I had 3 input boxes...

See if this parses correctly...

Company.first.receipts
Company.first.sellers
Seller.first.companies
Seller.first.receipts
Receipt.first.company
Receipt.first.seller

Posted in A `has_one :through` association issue

I believe you want to create your assiciations more like this:

#seller.rb
has_many :receipts
has_many :companies, :through => :receipts

#company.rb
has_many :receipts
has_many :sellers, :through => :receipts

#receipt.rb
belongs_to :company
belongs_to :seller

This would give you methods such as

Company.first.receipts
Company.first.sellers
Seller.first.companies
Seller.first.receipts
Receipt.first.company
Receipt.first.seller

*edited

Try this association then update your controller as necessary. If you still can't get it to work as you want, include your controller action so I can see exactly how you're trying to save your object.

Posted in Prevent spam bots from hitting app

@amalrik - the problem isn't that the bots are submitting a form, the problem is that they're hitting a no-longer publically accessible link every few seconds which is eating up bandwidth and system resources. The only way to stop this abuse of resources is to block the request before it even hits the webapp, so the incoming request has to be blocked further up (or down?) the stack (which is what stack-attack does) or somewhere at the network layer before it even hits the server (which is what CloudFlare does)

Posted in Prevent spam bots from hitting app

Ouch, that distributed of an attack is a different story all together!

If frequency of random connections is an issue like you're expericing here, you can also look into 3rd party services like CloudFlare: https://www.cloudflare.com/ddos/ which can help mitigate things before they even hit your network. I've used them in the past and been overall really pleased with their performance.

Very interesting fix with rack-attack you have there, I'm going to have to look into that one, thanks for posting your solution!

Posted in Prevent spam bots from hitting app

If things get too bad you can always blackhole the IP range temporarily or permanently - usually after so many failed connections the bots will go away...

ip route add blackhole IP/{8/24/32} changing ip/{options} to fit the range you want to blackhole... so you could do something like ip route add blackhole 203.160.52.0/24 and that would block all requests coming in from 203.160.52.0 - 255

When I experience high hits like this, I will usually tail -f the logs and monitor the IP addresses, as they roll through I'll keep adding them to the blackhole list.

Posted in Update and validate multiple entries

Hmm, this I'm not sure of. Someone with more knowledge of transactions and/or validations may have a solution if it's even possible...

From my understanding, a transaction gets rolled back as soon as there are any exceptions thrown. This is why when you have 3 validations, it will roll back the very first time an exception is thrown, so the remaining 2 validations aren't even ran (I think at least, but I could be wrong here).

You may end up having to make a custom validation to check the data before it's even handed over to the transaction. This should be fine to do if it's simple validations, like presence or data type. However, if you have to check for uniqueness then it would result in extra hit to the DB and wouldn't necessarily protect you from a race condition.

Posted in Update and validate multiple entries

Oh sweet, glad that worked out!!

Posted in Update and validate multiple entries

I'm not completely sure since I have very limited experience with making an API with Rails, but could your problem be solved by wrapping your find/save/update in a transaction?
Something like:

ActiveRecord::Base.transaction do
  api_fields.each do |api_field|
    content_model_field = @content_entry.content_model_fields.where(field_id: api_field).first
    content_entry_field = @content_entry.content_entry_fields.where(content_model_field_id:: content_model_field.id).first_or_create

    content_entry_field.update_attributes(value: params[:entryData][:fields][api_field.to_sym])
  end
end

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
No clue if this would actually work, just throwing it out there =D

Posted in How do I submit multiple checked items?

Sweet! That was a bit of a roller coaster! :)

If you're going to be working on this for awhile and think you'll need help often, it would help to make a repo that could be cloned and ran locally... if that's an option of course. If so let me know, I'd love to take a deeper look at what you're doing with this project.

Posted in How do I submit multiple checked items?

To make it shorter, I believe you can do this:

@venues = params[:venue_ids]
@variants = params[:variant_ids]

@venues.each do |v|
  @variants.each do |pv|
    @back_bar = BackBar.new(venue_id: v, product_variant_id: pv, product_id: params[:product_id])
    @back_bar.save!
  end
end

If you have validations, then as far as I'm aware you can't do the bulk saving (mass insert) since it still has to check each object on save. If anyone has knowledge how to do this mass insert with validation I'd love to know!

Posted in How do I submit multiple checked items?

Ack, wait - this isn't right either. This is why it's so hard to trouble shoot stuff without being able to run the code - simple stuff is easy to overlook =D

@venues = params[:venue_ids]
@variants = params[:variant_ids]

@venues.each do |v|
  @variants.each do |pv|
    @back_bar = BackBar.new
    @back_bar.venue_id = v
    @back_bar.product_variant_id = pv
    @back_bar.product_id = params[:product_id]
    @back_bar.save!
  end
end

Have to move @back_bar.venue_id = v down into the @variants loop since we moved @back_bar = BackBar.new down as well.

Posted in How do I submit multiple checked items?

Hard for me to say which way is better - I prefer my way just because I understand it and I like service objects :D but their suggestion may be valid or better. Although I am a little thrown off by their methodology... doesn't feel very "Railsy"

I should have refreshed myself on your original question and subsequent posts... so I'm going to back track a little. Using your original .each way (below) - did it work as expected?

@back_bar = BackBar.new
@venues = params[:venue_ids]
@variants = params[:variant_ids]

@venues.each do |v|
  @back_bar.venue_id = v

  @variants.each do |pv|
    @back_bar.product_variant_id = pv
    @back_bar.product_id = params[:product_id]
    @backbar.save!
  end
end

If not, then I bet your problem is calling BackBar.new outside of your loops, so it's only be instantiated once. You'd need to do this instead:

@venues = params[:venue_ids]
@variants = params[:variant_ids]

@venues.each do |v|
  @back_bar.venue_id = v

  @variants.each do |pv|
    @back_bar = BackBar.new
    @back_bar.product_variant_id = pv
    @back_bar.product_id = params[:product_id]
    @back_bar.save!
  end
end

Let me know if this works now. If so, then you can look into making it more robust / efficient.

Posted in How do I submit multiple checked items?

Hard to diagnose without seeing exactly what you have, but you may want to byebug in a few places to see what the data looks like at each step and do kind of a "duh" check to see if it makes sense...

to_save_array = []

@venues.each do |v|
  @back_bar.venue_id = v

  @variants.each do |pv|
    @back_bar.product_variant_id = pv
    @back_bar.product_id = params[:product_id]
    to_save_array << @back_bar
    byebug
  end
  byebug
end

byebug
BackBar.save!(to_save_array)

For reference, check out this gist => https://gist.github.com/nanosplit/a42d1c18b5eca01654563cfb3bb8c22f
It's setup a bit different than what I showed above since I can't do a mass save (model has validations) but shows how I'm making my own set of params to then create a new object from them. So you may try mimicking this setup to see if you can at least get it to property save each unique record, then worry about making it more efficient later.

Posted in How do I submit multiple checked items?

Yeah, basically after each iteration, @back_bar is a new BackBar object that has values based on what you passed to it. So you can now do something like:

to_save_array = []

@venues.each do |v|
  @back_bar.venue_id = v

  @variants.each do |pv|
    @back_bar.product_variant_id = pv
    @back_bar.product_id = params[:product_id]
    to_save_array << @back_bar
  end
end

BackBar.save!(to_save_array)

You may need to tinker with the save part some, I didn't test this but this should be what's needed if I recall correctly since save is able to take a single object or an array of objects. Also note I didn't do this in a transaction, while not required it can help, but I'd suggest getting this working first before adding the complexity of a transaction. Let me know if you have further problems and I'll take a look at what I did in one of my projects.

Posted in How do I submit multiple checked items?

Oops, I just noticed I had an error in my original post:

def some_function
  invoices = params[:invoices]
end

should be

def some_function
  invoices = params[:invoice_ids]
end

So when you say "I want to create a new row for each venue and variant.", in your example you'd end up with a total of 2 records, but if you had 2 variant_id's, then you'd have a total of 4 records?

If this is the case then as far as I am aware your way is fine, there might be a sleeker or more "Railsy" way of doing it that someone else could share. You may consider building a hash/array of new BackBar objects then do a mass save in a transaction. This would allow you to handle any errors during the transaction more elegantly.

Posted in How do I submit multiple checked items?

I could have sworn Chris had a video that talked about this but I'm not able to find it...

If you search for rails multiple checkboxes you'll get quite a few results and there's a Railscast episode that covers it really well. I'm not sure if it's kosher to post another video so I'll let you handle the Googling :)

But the basics are in your form you'll need something like

<% @invoices.each do |invoice| %>
  <%= check_box_tag "invoice_ids[]", invoice.id %>
<% end %>

which submits to a method in your controller that then, in this case would:

def some_function
  invoices = params[:invoices]
end

From there, do whatever you want with the array of invoice id's

Hope it helps!

Posted in Multiple select for CSV Export

I haven't done this personally but I have some very similar scenarios and I think that if I were doing it, I'd setup a form that has all the options for your user to select which submits their selections to a custom function that will take that input, run my queries, and generate an array or hash to then pass to the csv save function.

Posted in Pull data from another table in a lookup

Sweet, I'll have to play around with it, I love a good editor! :)

Did you ever mess with Summernote? http://summernote.org/examples/#hint-for-mention
They support mentions out the box it looks like. I use it on a site and have had no real issues so far.

Anywho - thanks again, and great job!!

Posted in Pull data from another table in a lookup

Woah, very clean!

Think you'll be sharing some of the techniques you used? I'm digging this WYSIWYG editor!

Thanks Chris! :)