Nested Attributes Not Setting Child IDs

Developing in Rails 5 recently I was struggling to think of why my child record IDs were not being set automatically on create. I thought this happened automatically. Then I discovered that setting inverse_of in the model is vital for accessing parent models from the child without relying on a pre-existing physical record (e.g. when you are creating new records). It turns out it’s been like this since Rails 2. How blind was I!

Here’s how it works:

class Publisher < ApplicationRecord
  has_many :articles, index_errors: true, dependent: :destroy, inverse_of: :publisher
  accepts_nested_attributes_for :articles, allow_destroy: true

class Article < ApplicationRecord
  belongs_to :publisher, inverse_of: :articles
  has_many :comments, index_errors: true, dependent: :destroy, inverse_of: :article
  accepts_nested_attributes_for :comments, allow_destroy: true, reject_if: proc { |item| item[:message].blank? }

class Comment < ApplicationRecord
  belongs_to :article, inverse_of: :comments

So using inverse_of allows me to access self.article from the Comment model even when the physical record has yet to be created.

Automated Rsync over SSH

The Mission

Let’s say we want to set-up rsync over SSH to securely backup a folder from one server to another. Our aim is to run a daily backup in cron with a command like this:

rsync -avz -e ssh /home/somefolder/important_files remoteuser@target_host:/home/mybackup/important_files_copy

On the Target Machine

The following steps work well for me but change as you wish (you may wish to create a folder under an existing user for example):

  1. Create a folder for the backup user:
    cd /home
    mkdir mybackupuser
  2. Next create the user, update the folder permissions and set the user password (make a note of this password):
    useradd -d /home/mybackupuser mybackupuser
    chown mybackupuser.root mybackupuser
    chmod 750 mybackupuser
    passwd mybackupuser
  3. Update the sshd_config file to allow this user to be used for ssh logins:
    vi /etc/ssh/sshd_config

    Add or amend the “AllowUsers” directive:

    AllowUsers mybackupuser
  4. Create the hidden folder for authorized keys:
    cd /home/mybackupuser
    mkdir .ssh
    chown mybackupuser.root .ssh
    chmod 700 .ssh
  5. Create the security script (attempt to filter any ssh command except rsync –server):
    cd /home/mybackupuser
    vi valid-rsync

    Copy and paste the following lines and then save the file:

    #!/bin/sh
    
    case "$SSH_ORIGINAL_COMMAND" in
    *\&*)
    echo "Rejected"
    ;;
    *\(*)
    echo "Rejected"
    ;;
    *\{*)
    echo "Rejected"
    ;;
    *\;*)
    echo "Rejected"
    ;;
    *\<*)
    echo "Rejected"
    ;;
    *\`*)
    echo "Rejected"
    ;;
    *\|*)
    echo "Rejected"
    ;;
    rsync\ --server*)
    $SSH_ORIGINAL_COMMAND
    ;;
    *)
    echo "Rejected"
    ;;
    esac

    I cannot claim credit for writing the above script but unfortunately I can’t remember where I got it from originally. Suffice to say it seems to be quite widely distributed on the web. To whoever wrote it: thank you!

  6. Set privileges for this file:
    chown mybackupuser.root valid-rsync
    chmod 700 valid-rsync

On the Source Machine (mostly!)

Now, in case you were getting bored, we move to the source machine to create an ssh key. The public part of this key will then be copied to the target machine.

  1. Log in as the user that your backups will run under. For example, if your backup script will run under the root user (usual) log in as root (or sudo su).
  2. Generate an SSH key pair:
    ssh-keygen -t rsa -b 2048

    Or, if it’s not your own server then you might want to specify a path for the key generation (rather than the default which is ~/.ssh/id_rsa):

    ssh-keygen -t rsa -b 2048 -f /home/someuser/rsync-key
  3. Important: accept all defaults and just press [Enter] when asked for the passphrase
  4. Upload the file from the source machine to the target machine using secure copy:
    scp ~/.ssh/id_rsa.pub mybackupuser@target_host:.ssh/authorized_keys

    If you specified a path (the -f option) then use the following command:

    scp /home/someuser/rsync-key.pub mybackupuser@target_host:/home/mybackupuser

    Now append the contents of rsync-key.pub to /home/mybackupuser/.ssh/authorized_keys on the target machine.

  5. On the target machine, prefix the key with additional security measures including the ip address and valid-rsync command file that you created earlier:
    from="xx.xx.xx.xx",command="/home/jjbb/valid-rsync" ssh-rsa ASHAKJSDHhaisudhfaksjfhHAISUDHiauegfkjaHSDKJHDjkh.....

    “xx.xx.xx.xx” is the IP address of the source machine.

  6. Now you are ready to rsync:
    rsync -avz -e ssh /home/somefolder/important_files remoteuser@target_host:/home/mybackup/important_files_copy

    If you are using your own file (see -f option earlier) you must add “-i /home/someuser/rsync-key” to the ssh options thus:

    rsync -avz -e "ssh -i /home/someuser/rsync-key" /home/somefolder/important_files remoteuser@target_host:/home/mybackup/important_files_copy

Disable Private Browsing / Incognito Mode

Private browsing may be handy if you want to cover your tracks; naturally you are not looking at anything you shouldn’t but merely planning a nice surprise for a loved one and don’t want them to find out. However, if you are a parent seeking to protect their children or an employer who doesn’t want their employees wasting time then disabling private browsing is a helpful step in reducing temptation: if they know they can’t browse privately then they may be less inclined to look at stuff they shouldn’t.

Internet Explorer

IE requires a Windows Registry edit. Simply paste the required settings from the lines below into a text file (e.g. “ie.reg”) and then “run” it to merge these settings into the Windows Registry.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Control Panel]
"DisableDeleteBrowsingHistory"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Internet Explorer\Privacy]
"EnableInPrivateBrowsing"=dword:00000000

[HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel]
"DisableDeleteBrowsingHistory"=dword:00000001

[HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Privacy]
"EnableInPrivateBrowsing"=dword:00000000

I believe this works on versions 8, 9 and 10. Please let me know if not. I have included settings for both the whole machine and current user, you don’t actually need both.

I have also included the “DisableDeleteBrowsingHistory” setting as this is useful.

Firefox

Firefox is the easiest. You simply have to install the “Disable Private Browsing Plus” add-on and then you can do what many marketers do like buying youtube views for example. Once added it cannot be easily removed once added. You can find it here:

https://addons.mozilla.org/en-US/firefox/addon/disable-private-browsing-pl/?src=api

Google Chrome

Chrome used to accept registry settings similar to IE but that is no longer the case. You now need to download and install Group Policy Templates from here:
http://dl.google.com/dl/edgedl/chrome/policy/policy_templates.zip

Then follow this procedure:

  1. Unzip the policy_templates.zip file.
  2. From the Windows Start button enter “gpedit.msc” in the search box and press [Enter]. This will open the Local Group Policy Editor.
  3. Either under Computer Configuration or User Configuration (as you wish), right-click on “Administrative Templates” and click “Add/Remove Templates”.
  4. Click “Add” and open the file “policy_templates\windows\adm\en-GB\chrome.adm” (replace the “en-GB” with your own country).
  5. Once installed, open up the “Administrative Templates” and you will see either a new folder “Google” or a new folder “Classic Administrative Templates (ADM)”. The latter on Windows 7/8.
  6. Open up “Google” and then click on “Google Chrome” and you will see a whole raft of settings (for more info: http://www.chromium.org/administrators/policy-list-3).
  7. Double-click “Incognito mode availability” and a dialog will open.
  8. Now the confusing bit: select “Enabled” and then in the drop-down list underneath select “Incognito mode disabled”.
  9. You can check which policies are active by going to “chrome://policy/” in Chrome.

For more information please see this article:
https://support.google.com/chrome/a/answer/187202?hl=en