Sunday, 20 April 2025

all ec2 instance pg as remote access(EC2)

Is Blog se local se server per data create kar sakte hai.

1. On each EC2 instance, edit the PostgreSQL configuration file

1.1 sudo nano /etc/postgresql/<version>/main/postgresql.conf

# or for Amazon Linux

sudo nano /var/lib/pgsql/<version>/data/postgresql.conf

--

Update this line:

listen_addresses = '*' OR 
listen_addresses = '0.0.0.0'

---------------------------------------------------------------

2. Edit pg_hba.conf to Allow Remote Connections

On each instance, edit the pg_hba.conf file:

sudo nano /etc/postgresql/<version>/main/pg_hba.conf # or sudo nano /var/lib/pgsql/<version>/data/pg_hba.conf

Add the following line at the end (replace CIDR with the IP or IP range you want to allow):

host all all 0.0.0.0/0 md5

-----------------------------------------------

3. Open Port 5432 in EC2 Security Groups(This is most important)

Go to AWS EC2 Console → Security Groups, and for each EC2 instance:

  1. Find the associated Security Group.

  2. Click Inbound rulesEdit inbound rulesAdd rule:

    • Type: PostgreSQL

    • Protocol: TCP

    • Port Range: 5432

    • Source: Custom → <Your IP>/32 (or 0.0.0.0/0 for all IPs, use with caution)

----------------------------------------------------

4. Restart PostgreSQL

After making changes:

sudo systemctl restart postgresql # or sudo service postgresql restart
---------------------------------

5. Connect Remotely

Now you can connect from your local machine using a PostgreSQL client:

psql -h IP -U user_name -d database_name

ec2-ip: Server Ip address

username: Server pg username

6. Update Database.yml file

default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV["DATABASE_USERNAME"] %> password: <%= ENV["DATABASE_PASSWORD"] %> database: <%= ENV["DATABASE_NAME"] %> host: <%= ENV["DATABASE_HOST"] %> development: <<: *default staging: <<: *default test: <<: *default production: <<: *default


Application.yml file

development:

  DATABASE_NAME: "database_name" # This is server database name

  DATABASE_HOST: "IP"

  DATABASE_USERNAME: "Server pg username"

  DATABASE_PASSWORD: "Server pg password"

Thursday, 10 April 2025

Sidekiq restart with new updation(like: update time, add new job(worker))

 1. ps aux | grep sidekiq

Get output: ubuntu    1111111  0.0  0.0   7008  2432 pts/0    S+   10:28   0:00 grep --color=auto sidekiq

2. kill -9 1111111

3. bundle exec sidekiq -d -L log/sidekiq.log

4. sudo service redis-server restart

5. sudo systemctl restart sidekiq

Wednesday, 26 February 2025

Send attachment with mail in rails

 Routes: 

post "/send_email_with_attachment", to: "articles#send_email_with_attachment"

-----------------------------------

Controller:

class ArticlesController < ApplicationController

  def send_email_with_attachment

    email = "arvind@gmail.com"

    attachment = params[:attachment]

    # Save the file temporarily

    file_path = Rails.root.join('tmp', attachment.original_filename)

    File.open(file_path, 'wb') do |file|

      file.write(attachment.read)

    end

    MyMailer.send_email_with_attachment(email, file_path).deliver_now

    # Delete the temporary file after sending the email

    File.delete(file_path) if File.exist?(file_path)

    redirect_to root_path, notice: 'Email sent successfully'

  end

end


--------------------------

Mailer

class MyMailer < ApplicationMailer

  def send_email_with_attachment(email, attachment_path)

    @greeting = "Hi"

    attachments[File.basename(attachment_path)] = File.read(attachment_path)

    mail(to: email, subject: 'Email with Attachment')

  end

end

-------------------------------

View
Form view:

<%= form_tag "/send_email_with_attachment", class: "inline-form", multipart: true do %>
  <%= file_field_tag :attachment %>
  <%= submit_tag 'Send Email' %>
<% end %>

Mailer view:

<h1>My#send_email_with_attachment</h1>

<p>
  <%= @greeting %>, find me in app/views/my_mailer/send_email_with_attachment.html.erb
</p>

----------------------------

Development.rb

config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.default_options = {from: 'localhost:3000'}
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    domain:               'localhost',
    user_name:            ENV["SMTP_EMAIL"],
    password:             ENV["SMTP_PASSWORD"],
    authentication:       'plain',
    enable_starttls_auto: true
  }


public bucket on AWS s3

 Please visite: https://alex-okorkov.medium.com/how-to-set-up-aws-s3-bucket-on-rails-with-activestorage-d384075ce773

--------------------


Code:

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Effect": "Allow",

            "Principal": "*",

            "Action": "s3:ListBucket",

            "Resource": "arn:aws:s3:::newlogoimages"

        },

        {

            "Effect": "Allow",

            "Principal": "*",

            "Action": [

                "s3:PutObject",

                "s3:GetObject",

                "s3:DeleteObject"

            ],

            "Resource": "arn:aws:s3:::newlogoimages/*"

        }

    ]

}



Thursday, 9 January 2025

Add nested form in rails 7

 1. Add Gem

gem "nested_form"

Run$ : bundle 
----------------
2. Created new file : app/javascript/js/nested_form.js

rails g nested_form:install
jb ye line run karege to public ke ander >> public/javascript/js/nested_form.js file generate hogi, lekin nested_form.js ka code is directory me add kar dena >>  app/javascript/js/nested_form.js

app/javascript/js/nested_form.js

(function($) {
  window.NestedFormEvents = function() {
    this.addFields = $.proxy(this.addFields, this);
    this.removeFields = $.proxy(this.removeFields, this);
  };

  NestedFormEvents.prototype = {
    addFields: function(e) {
      // Setup
      var link      = e.currentTarget;
      var assoc     = $(link).data('association');                // Name of child
      var blueprint = $('#' + $(link).data('blueprint-id'));
      var content   = blueprint.data('blueprint');                // Fields template

      // Make the context correct by replacing <parents> with the generated ID
      // of each of the parent objects
      var context = ($(link).closest('.fields').closestChild('input, textarea, select').eq(0).attr('name') || '').replace(new RegExp('\[[a-z_]+\]$'), '');

      // context will be something like this for a brand new form:
      // project[tasks_attributes][1255929127459][assignments_attributes][1255929128105]
      // or for an edit form:
      // project[tasks_attributes][0][assignments_attributes][1]
      if (context) {
        var parentNames = context.match(/[a-z_]+_attributes(?=\]\[(new_)?\d+\])/g) || [];
        var parentIds   = context.match(/[0-9]+/g) || [];

        for(var i = 0; i < parentNames.length; i++) {
          if(parentIds[i]) {
            content = content.replace(
              new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'),
              '$1_' + parentIds[i] + '_');

            content = content.replace(
              new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]', 'g'),
              '$1[' + parentIds[i] + ']');
          }
        }
      }

      // Make a unique ID for the new child
      var regexp  = new RegExp('new_' + assoc, 'g');
      var new_id  = this.newId();
      content     = $.trim(content.replace(regexp, new_id));

      var field = this.insertFields(content, assoc, link);
      // bubble up event upto document (through form)
      field
        .trigger({ type: 'nested:fieldAdded', field: field })
        .trigger({ type: 'nested:fieldAdded:' + assoc, field: field });
      return false;
    },
    newId: function() {
      return new Date().getTime();
    },
    insertFields: function(content, assoc, link) {
      var target = $(link).data('target');
      if (target) {
        return $(content).appendTo($(target));
      } else {
        return $(content).insertBefore(link);
      }
    },
    removeFields: function(e) {
      var $link = $(e.currentTarget),
          assoc = $link.data('association'); // Name of child to be removed
      
      var hiddenField = $link.prev('input[type=hidden]');
      hiddenField.val('1');
      
      var field = $link.closest('.fields');
      field.hide();
      
      field
        .trigger({ type: 'nested:fieldRemoved', field: field })
        .trigger({ type: 'nested:fieldRemoved:' + assoc, field: field });
      return false;
    }
  };

  window.nestedFormEvents = new NestedFormEvents();
  $(document)
    .delegate('form a.add_nested_fields',    'click', nestedFormEvents.addFields)
    .delegate('form a.remove_nested_fields', 'click', nestedFormEvents.removeFields);
})(jQuery);

// http://plugins.jquery.com/project/closestChild
/*
 * Copyright 2011, Tobias Lindig
 *
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 */
(function($) {
        $.fn.closestChild = function(selector) {
                // breadth first search for the first matched node
                if (selector && selector != '') {
                        var queue = [];
                        queue.push(this);
                        while(queue.length > 0) {
                                var node = queue.shift();
                                var children = node.children();
                                for(var i = 0; i < children.length; ++i) {
                                        var child = $(children[i]);
                                        if (child.is(selector)) {
                                                return child; //well, we found one
                                        }
                                        queue.push(child);
                                }
                        }
                }
                return $();//nothing found
        };
})(jQuery);

--------------------------------------------
4. config/importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "nested_form", to: "js/nested_form.js"
pin_all_from "app/javascript/controllers", under: "controllers"
pin_all_from "app/javascript/js", under: "js", preload: true

------------------------------------------------
5. app/javascript/application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "js/bootstrap.bundle.min"
import "js/simple-datatables"
import "js/quill.min"
import "js/tinymce.min"
import "js/validate"
import "js/main"
import "nested_form";
--------------------------------------------
6. User.rb
has_many :products, dependent: :destroy
  accepts_nested_attributes_for :products, allow_destroy: true
-----------------------------
7. Product.rb
class Product < ApplicationRecord
belongs_to :user
end
------------------------------------------

8. On form
<%= simple_nested_form_for @user, url: user_path(@user), html: { class: 'row g-3', "data-turbo": false } do |f| %>

<div class="col-md-6 mt-4">
         <label class="form-label">Bericht</label>
            <%= f.input :email, input_html: { class: "form-control form-control-sm", rows: 5 }, label: false %>
        </div>

<h3>Products</h3>
  <div id="products">
    <%= f.fields_for :products do |product_form| %>
      <div class="nested-fields">
        <%= product_form.label :name, "Product Name" %>
        <%= product_form.text_field :name %>

        <%= product_form.link_to_remove "Remove" %>
      </div>
    <% end %>
  </div>
        <%= f.link_to_add "Add a products", :products, :data => { :target => "#products" } %>

<% end %>
-------------------------------------------------

9. User controller.rb
def users_params
    params.require(:user).permit(:email, products_attributes: [:id, :name, :_destroy])
  end