Activity
I think for resque, you'll need to pass in the tenant into the job as an extra parameter so that you can set the tenant in the beginning.
This is how apartment-sidekiq works https://github.com/influitive/apartment-sidekiq
Sidekiq is probably a better solution anymore than Resque. It's a lot faster and much better supported so if you haven't written too much Resque code, it might be worth switch to using the apartment-sidekiq gem with Sidekiq. It'll take care of passing in and switching to the tenant for you automatically.
For security, there's a few things you can do like setup a firewall and only open port 80 or 443 for web, setup fail2ban, and disable password authentication over SSH. You'll want to be careful not to lock yourself out of the server, but the recovery console can still let you in if you do. :) More stuff to checkout https://wiki.ubuntu.com/Bas...
Pingdom is probably the most used one, but there are a bunch if you search for monitoring. I use Pingdom's free service I think.
There's a cool little trick that if you change the youtube URL from "youtube.com" to "ssyoutube.com" it will redirect and give you a link to download the video like this:
This might work. You'll have to test it inside the class methods to find out if the Apartment::Tenant is correctly set to verify that it's working. I imagine it would, but you can just print out the current tenant to verify it.
Possibly a better solution would be to loop through the companies inside the methods themselves instead. That would give you a bit more control over setting the tenants.
Hmm that sounds right. Are you able to share an example app that I could take a look at? Not sure I can give you any more pointers without fiddling with some code.
This a good question and is semi-complex so there are a ton of different approaches to it.
One of the ideas that's related to this (which isn't necessarily the right way to go) is Single Table Inheritance. It lets you define a singe "Service" table in your database and then have a "type" associated with it so that you could have ChefService, MusicianService, etc all stored in the same place. I would say this is a bad idea because you're going to have a lot of extra columns on the table that aren't associated with the service, but it's a step in thinking in the right direction.
There are a bunch of different ways you could do this. One option would be to create a bunch of different tables for these and just store them separately. Another would be to create a Service table, and have two other tables "RequiredFields" and "FieldAnswers". You could create the BaseService like normal, and then based upon the "type" column, you could reference the RequiredFields table and look up ones that match that type. You'd have a record for each like
RequiredField (service_type, name, format)
- service_type: "chef", name: "cuisine", format: "string"
- service_type: "chef", name: "dietary_type", format: "string"
- service_type: "chef", name: "max_people", format: "integer"
- service_type: "musician", name: "genre", format: "string"
- service_type: "musician", name: "instrument", format: "string"
- etc
And then this could generate a form dynamically based upon the fields and types. Then when they fill out the form, you can save their results into a FieldAnswers table that stores the RequiredField ID and the answer.
Another option would be to group all these into serialized hashes in a text field. It's somewhat limiting, but could also work.
Also this is where database like Mongo are a bit better suited because you can store a "Service" and have different types of attributes easily included. You don't have to define your data structure ahead of time, but it has plenty of other gotchas that you'll want to look into first. If you're down to learn all that, Mongo might be a good solution for you.
Posted in Advanced Search, Autocomplete and Suggestions with ElasticSearch and the Searchkick gem Discussion
Check out something like this https://gist.github.com/Glo...
Posted in Advanced Search, Autocomplete and Suggestions with ElasticSearch and the Searchkick gem Discussion
You'll either need to do separate searches and combine the results or index one main model and include the nested models attributes in the index.
Posted in Advanced Search, Autocomplete and Suggestions with ElasticSearch and the Searchkick gem Discussion
Hey Aime! Sorry, I've been meaning to get back to you but have been behind.
Source code: https://github.com/excid3/g...
And searching multiple models works a bit differently. For example, you would want to index and search Post, but the fields you would index should include both the comments and tags. This is what I did for indexing tags in the example.
Another way to do it would be to search those separately and combine the results. Facebook does it this way for example.
Posted in Firefox rendering issues
Hmm, you're right. I would check a couple things:
- Make sure you're including any of the browser specific tags that you might be using for newer css styles. Make sure you include any of the
-moz
ones just in case https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions - Verify your CSS isn't missing any curly braces or anything. For example it looks like
.tab-container .etabs
works just fine in Chrome but on Firefox that's not getting matched. Seems odd, so maybe the CSS for that specific tag has some error that causes it not to get parsed properly in Firefox.
Turbolinks actually does all of what you're describing with the new partial functionality. I made a video on it on another service that I was fiddling with.
You can check out the video here: https://www.livecoding.tv/video/new-turbolinks-3-features-with-ruby-on-rails/
Posted in Subscriptions with Stripe Discussion
You can swap a lot of the JS out with the Stripe Checkout button. The same process works there. You'd keep the token callback and server-side code. It's pretty much the same minus the form and the JS listener for submit. :)
This is an awesome question. I've dealt with this in the past and I'm also going to be adding a "watched" feature to GoRails. So how do you tackle it efficiently?
There's a bunch of different ways to go about this but they'll all involve caching of some sort.
- Easiest option is to simply just render the thumbnails without the "watched" functionality and then change the thumbnail class when the page loads via AJAX. Use JS to gather all the thumbnail video IDs on the page, make one request to the server to see the user's status on each of those, return the result back, and then add a "watched" class to the thumbnails that triggers the CSS to display that.
This would be super easy to build and would be pretty efficient. Basecamp has talked about using this approach in their app in a few places. Super lightweight and also allows you to cache the thumbnails globally. The results of the watched AJAX request can also be cached and you can bust the cache when the user watches a video. This would make it pretty quick and the page load/parsing time should be fast enough that it wouldn't be hugely noticeable.
This approach breaks down when your "watched" AJAX response is slow. Users would see the thumbnail and then some time later it would change to be "watched" which could be an odd user experience. Therefore... option #2.
- The second option is to cache the "watched" state of the thumbnail for each video. You can render your page like you mentioned above, but cache the thumbnails and toss the current user in the scope so you can have a cache for each user and their watched status. When they watch a new episode, only the cache for that user and that episode would change.
Basically just doing this around the thumbnails:
<%= cache [current_user, video] do %>
<% if current_user.watched?(video) %>
<% else %>
<% end %>
<% end %>
In both these cases, the best bet will be to make one single query of the user's activity to get all the user's watched videos at once instead of separate queries.
Instead of a bunch of queries hitting the databaselike this:
current_user.activities.where(status: "watched", video: @video).any?
Load them all up, and do a quick lookup instead
@watched_video_ids = Video.joins(:activities).where(activities: {status: "watched", user: current_user}).pluck(:id)
And in your views, you can just check if the video is in the instance variable instead of hitting the database
<% if @watched_videos.include?(video.id) %>
# watched
<% else %>
<% end %>
In the short term, both of those solutions will be most efficient by loading up all the watched videos at once (until they've watched thousands of videos of course) and then just checking that array rather than going to the database each time.
Your mileage may vary, and the most efficient solution in the long term will really be determined by how usage of your app ends up being. For something like GoRails, there aren't that many episodes so loading up an array of each video ID that you've watched will be pretty quick. For YouTube...that's a whole different story and they'll probably do a much different solution. But they've got the time and money to spare for that. 😉
Posted in Stripe Payments
Always the easy things! 😉
Last night I got tripped up on making a pluralization mistake for like 45 minutes. :)
Posted in Stripe Payments
It sounds like you've got everything but may just need to restart your rails server to pickup the constant in the config file. Have you tried that?
This is an interesting one. I would do one of two things to assume the order for the records:
- I would use the database ID order or created_at to determine the order and
- I would mark those as taken or "complete" as you mentioned.
With #1, you could assume that you've got the items in order as they came in. You could store each item individually as a record, or the batches that are put into stock and then count down. If you do the latter, you would want to keep a quantity and used count, so once the used count equals the quantity, that batch would be assumed used. I'll just show some example stuff that assumes there are individual records for every item.
class Item
scope :available, ->{ where(used: true) } # Let us easily grab the available items
end
has_many :items, ->{ order(created_at: :asc) } # this can have a default ordering set like this so they're always accessed in order
def take_items(quantity)
taken_items = items.available.limit(quantity) # Grab X number of items
taken_items.update_all(used: true) # Mark all of these as used
taken_items # Return the taken items, so then the caller could sum the price (taken_items.map(&:price).sum or something similar)
end
Does this direction make sense to you?
That sounds about right. Ffmpeg isn't installed by default. You can probably use this: https://elements.heroku.com...
It's /vagrant
Duplicate table as in database table from a migration?
If you want the entire thing to roll back on any failure, you can put the transaction around the foreach.