Chris Oliver

Joined

290,590 Experience
86 Lessons Completed
296 Questions Solved

Activity

Posted in File Uploads with Refile Discussion

This looks super cool. I haven't used it before, so I'm not quite sure how they return the urls afterwards. I have previously seen a lot of people using https://www.filepicker.com/ in the past.

I think they're definitely great and give your users a lot of flexibility as well saving you from a lot of time managing the files and processing them. Would definitely recommend it if file uploading is something you don't really need to manage or customize too deeply.

Posted in Liking Posts Discussion

You'll need to make sure you pass the book into the partial because they have different scopes for local variables.

Posted in Liking Posts Discussion

So when you loop through each book, you need to reference the "book" local variable, not the "@book" instance variable when rendering the button. This is because the each yields the current book in the loop to the code inside the each block so it can run multiple times every book in the array.

Posted in Simple newsletter sign up?

Alright, I got an episode recorded for you! http://videos.gorails.com/medias/4h3x4wsnhp

Give it a watch and see what you think. I'm curious how you feel about the speed of the episode. I touched on a lot of things all at once but tried to break them down just enough. Hopefully you'll find it useful!

I think I'll try releasing this out as a full GoRails episode as well and see what people think.

Posted in Liking Posts Discussion

You can set up an association to get the liked books through the likes the user has. It follows basically the same format. Remember that your book variable from the each is actually a full Book record so you can print out the id, the title, or whatever just by changing what you reference. Here's an example that would list out the book titles that a user likes. (I haven't tested this so it may not work right off the bat)

class User
has_many :likes
has_many :liked_books, through: :likes, class_name: "Book"
end

<%= current_user.liked_books.each do |book| %>
<li><%= book.title %></li>
<% end %>

Posted in Setup MacOS 10.10 Yosemite Discussion

That's good to know. I'm curious as to why I've never had that issue, but I guess I'll make a note in there to restart your terminal just in case.

Posted in Sending emails with Mandrill Discussion

Glad you got it working! As an aside, one great way to test all this is to manually create and test your emails from the Rails console. It can help you poke around and find bugs like this quicker than going through the browser.

Posted in Simple newsletter sign up?

Great little project. Maybe I can record a screencast for this over the weekend. The gist of it is going to be really simple:

  1. You'll have a model called Lead or something like that. It will have columns for the attributes you want to store: email, name, device, etc.
  2. You'll set up a LeadsController that can have the create action to save the Lead and renders a response.
  3. On the action that displays the homepage (I'll just call this LeadsController#index for now), you would create a <%= form_for @lead, remote: true do |f| %> and in the controller, you would set @lead = Lead.new.
  4. An optional piece here is the remote: true option. This will set up the object, the form, and configure it to be sent via Javascript to the server. The server would return some Javascript back to update the page. One example would be to remove the form after it's submitted and replace it with a "Thank you!" message. Since you made a form for a new Lead, this form will send to the create action. You'd put your javascript in a create.js.erb view file if you went with the remote true option.
  5. That's pretty much it. You will probably want to store a cookie after create so that the next time the user visits the site again, they don't see the lead form twice.

You'll also need something to auto-detect the device probably unless you want the user to select it in the form. Something like this Browser gem might be helpful.

It's really not too hard, but it can be a lot to wrap your head around. This would make for a great screencast though, so I'll be sure to record a version of how to do this soon.

What parts here seem the most daunting?

AJAX is just a Javascript XMLHttpRequest. It's a full HTTP request, normally designed to retrieve XML but more recently JSON is the format of choice. The only real difference I believe is a header denoting it's an AJAX request.

Basically if the browser did not send over cookies during an AJAX request, those requests would be useless for any data manipulation and half the web wouldn't be able to work as designed. Including this comment form which is kinda crazy to think about.

Posted in Ecommerce multi-step checkout with guest accounts

Wizards are definitely a good topic to cover. I've used Wicked for wizards a few times and it seems pretty good if you follow the way it wants you to set up the pages. It does want a persisted record in the database to store the state of the wizard, so this approach would work well with it.

As for abandoned records, they might seem scary, but it's kind of interesting to keep around so you can analyze them later. You might notice that certain products are harder for customers to convince themselves to buy. And if you save their email you could email them 5 days later reminding them to check out (if that fits your business). Could be a lot of good uses for things like that.

Posted in Import CSV data using RubyZip and Postgresql COP

Yeah I'm curious what might be causing it to not crash but silently fail. Seems like you're close but something is just slightly wrong.

The trouble with rspec here would be that it'll tell you it didn't work, but not why which is the real question.

This is the session object that you've always interacted with behind the scenes if you've ever authenticated users in an app. You may not have known it, but that's where the login information is stored to determine if a user is signed in or not. It's a cookie which gets sent over with every request therefore telling the server the status of your session being logged in or out.

The gist is: there is nothing special you would need to do for multitenant applications other than store a list of users on each account and their permissions. You can use Pundit, CanCan, etc just like you normally would but your rules would be based off the user, the account, and the record you're trying to create or modify. You would need to pass in the account as the additional option here for proper scoping and validation.

If you are to rebuild Rails, you're going to need the ability to store a cookie in the browser to login a user. The simplest version is to set a cookie called "user_id" to the database ID so you can look it up with each request just like we do here with the Account. The problem is that for the User ID, you don't want someone to be able to change it, meaning your cooking should not store the ID in plain text. To make it secure, the cookie must be encrypted so the user cannot tamper with it. This security doesn't apply to the Account, because the account is public information (by way of being in the URL).

Does that make more sense?

Posted in Multitenancy with the Apartment gem Discussion

Yep! Rails knows to delegate that appropriately behind the scenes.

I believe you're over thinking the problem a bit around how the authorization would work. The user who is logged in cannot spoof their user because their ID is encrypted in the session. That User ID gets sent over every AJAX request so you will authorize that user's activity against the subdomain they POST'd too. Each account will need a list of users authorized to make changes on it that you authorize against. This prevents you from spoofing yourself as another user. You will basically treat them as having access to any account they are authorized on which is okay.

That said, you could modify the subdomain in the HTML, but it wouldn't matter because you would only be able to make changes on the authorized subdomains provided you set up your authorization correctly.

Posted in Populate dropdowns based on selection

Definitely want to do some AJAX for that. You can set up jQuery to listen to the first dropdown's change event. Then you can set up an endpoint like "/group/#{insert-dropdown-selected-value-here}/subgroups.json".

When the change fires, take the value, insert it into this url, and then request it via GET with jQuery's AJAX method. Then you can either have the subgroups.json return HTML for the options or a JSON array of subgroups. I would recommend the JSON array so it is more reusable in the future.

Lastly you would want your success callback for the AJAX request to transform the JSON array into <option> tags for the subgroup select and then you can replace the existing option tags with the new ones you just retrieved.

Does that make sense? You may be able to build a nice little controller concern for your different models or it might be easier to build a generic endpoint to hit so you only have to write this code once. Kinda depends on what data you want rendered in the JSON. If it's generic, then you can make your endpoint generic. If not, duplicating endpoints with a concern and then just modifying the JSON template might be the best solution.

Posted in Ecommerce multi-step checkout with guest accounts

So one thing to be aware of is that the session can't store too much information. You're limited in cookie size so it's usually not a great place to store much information. That said, it is perfect for storing an ID of a database record that might represent the Order.

You will probably want to create an Order object and then save the ID to it in the session to track it as the user progresses. You can use it to store the email and other information temporarily while they are checking out. Then, when they finally get to the final stage of checkout, you can use this Order ID from the session to create the actual Devise User and other records.

This would make the user account optional, but potentially leaves some data lying around. If the user decides to not purchase halfway through the order, you will have a leftover Order lying around that's unfinished. You can either keep it around (can't hurt to analyze later) or if you really need to remove it, you can have it expire after a couple days if it isn't marked as "complete". It also doesn't require you to capture an email or anything if you don't want.

There are lots of other ways to handle this and this is just one approach. I'm curious what suggestions other people might have.

Posted in Import CSV data using RubyZip and Postgresql COP

I love the idea of importing from a zip file.

I'm wondering where that might have gone wrong. It seems like it should have worked, but maybe the entry.get_input_upstream is not providing you the same value as it does when you're doing it without the Zip?

My suggestion would be to try inspecting the value of data in both cases and see if they are different in any way. That could be the issue there.

Posted in Setup MacOS 10.10 Yosemite Discussion

Yeah it's up to date. 4.2.1 has no difference in instructions, just a security patched version of 4.2.0.

Did you get XCode installed via the app store? Sometimes you need to restart your terminal to proceed. There's a lot of other information on this issue here: https://github.com/sparklem...

Posted in Deploy Ubuntu 14.04 Trusty Tahr Discussion

Definitely. That's one of my major goals to add to this tutorial. It's an important piece and I kind of glossed over it. I also need to do a screencast to explain how it works as well.

Posted in Pundit for RESTFUL actions on Model fields

Yeah, that's one of the nifty things that you can do with strong_params. It used to be that the allowed params were global, but in some cases you want to have different accepted attributes like this.