Brian Gilbank

Joined

6,970 Experience
43 Lessons Completed
3 Questions Solved

Activity

Posted in Iterating using css grid

I had to add partial and it worked. Cheers,

<%= render partial: 'card', locals: { gym: gym, index: index } %>

Posted in Iterating using css grid

Hmm, still throwing the same error.

Posted in Iterating using css grid

I had it originally in a partial, but it was throwing an error for undefined local variable or method for gym.

<% if gym.image.present? %>

Posted in Iterating using css grid

Omg! I will get this one day. Thanks again.

Posted in Iterating using css grid

it's not stopping at 3 when it counts, eg

def index
  @q = Gym.ransack(params[:q]) 
  @gyms = @q.result.includes(:province).page(params[:page]).order("created_at DESC").paginate(:page => params[:page], :per_page => 18)
end

Posted in Iterating using css grid

Hey Chris - Just a follow up on this question. I am seeing a bunch of duplicate entries: https://gympass.ca/fitness-facilities for some reason?

<div class="clubs__index">
      <% @gyms.each_slice(3) do |gyms| %>
       <% @gyms.each_with_index do |gym, index| %>
        <div class="clubs__index--<%= index + 1 %>">
         <%#= render 'gyms/card' %>
         <div class="card">
          <% if gym.image.present? %>
            <%= image_tag gym.image.url, class: 'card__image', alt: gym.gym_name, size: "700X500"  %>
          <% else %>
            <%= image_tag 'https://ficdn-files.ca/images/gympass/logo/default_club_image_index.jpg', class: 'card__image', loading: "lazy" %>
          <% end %>
          <h3 class="card__title"><%= gym.gym_name %></h3>
            <h5 class="card__address">
            <%= gym.gym_address.titleize %><br> 
            <%= gym.gym_city.titleize %> / <%= gym.province.name if gym.province %><br>
            <%= gym.gym_postal.insert(3, ' ').upcase %>
            </h5> 
            <p class="card__details">
            <span class="card__details--bold"><%= t("gyms_index.telephone") %></span>
            <%= number_to_phone(gym.gym_telephone, area_code: true ) %><br>
            <% if gym.ext.present? %>
              <span class="card__details--bold"><%= t("gyms_index.ext") %></span>
              <%= gym.ext  %><br>
              <% end  %>
            <% if gym.gym_email.present? %>
              <span class="card__details--bold"><%= t("gyms_index.email") %></span>
              <%= gym.gym_email.downcase %> 
            <% end %>
          </p>
          <p class="card__url">
            <% if gym.gym_website.present? %>
            <%= link_to url_for(gym.gym_website), target: '_blank' do  %>
            <%= truncate(gym.gym_website.downcase.try(:remove, /.*\/\//), :escape => false, :length => 44)  %>
            <% end %>
          <% end %>
          </p>
          <ul class="card__social">
            <% if gym.gym_facebook.present? %>
            <li class="card__social--items">
              <%= link_to gym.gym_facebook, target: '_blank' do %>
              <i class="card__social--icons fab fa-facebook-f"></i>
              <% end %>
            </li>
            <% end %>
            <% if gym.gym_twitter.present? %>
            <li class="card__social--items">
              <%= link_to gym.gym_twitter , target: '_blank' do %>
              <i class="card__social--icons fab fa-twitter"></i>
              <% end %>
            </li>
            <% end %>
            <% if gym.gym_instagram.present? %>
            <li class="card__social--items">
              <%= link_to gym.gym_instagram, target: '_blank' do %>
              <i class="card__social--icons fab fa-instagram"></i>
              <% end %>
            </li>
            <% end %>
            <% if gym.gym_youtube.present? %>
            <li class="card__social--items">
              <%= link_to gym.gym_youtube, target: '_blank' do %>
              <i class="card__social--icons fab fa-youtube"></i>
              <% end %>
            </li>
            <% end %>
          </ul>
          <% if logged_in? %>
          <ul class="card__admin">
            <li class="card__admin--items">
              <%= link_to 'View', gym, class: "link-padding" %>
            </li>
            <li class="card__admin--items">
              <%= link_to 'Edit', edit_gym_path(gym), class: "link-padding" %>
            </li>
            <li class="card__admin--items">
              <%= link_to 'Destroy', gym, method: :delete, data: { confirm: 'Are you sure?' }, class: "link-padding" %>
            </li>
          </ul>
          <% end %>                                       
        </div> <%# card %>

        </div>
       <% end %> <%# do block end %> 
      <% end %>

    </div>  <%# clubs index %>

Posted in Iterating using css grid

Awesome you saved me! It probably would have taken me a week to figure that out. Thank you.

I wanted to rebuild a site without using a CSS framework. But I will try out Tailwind on my next project.

Posted in Iterating using css grid

Hi Chris - I am using CSS grid for a three-column blog layout. Unfortunately, when I run the do bock it creates three instances of the same post. I guess this is to be expected.

Not sure how to get around this issue with CSS grid. Wondering if you might know of a fix?

I put a basic example below.

.someclass {
 display: grid;
 grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
}

Index page

<% @posts.each do |post| %>

# grid one
<div class="grid-1">
 <%= post.title %>
</div>

# grid two
<div class="grid-2">
 <%= post.title %>
</div>

# grid three
<div class="grid-3">
 <%= post.title %>
</div>

<% end %>

Posted in Tabs with Stimulus

Hahah!

Posted in Tabs with Stimulus

Thanks for the quick response, Chris. I switched computers and forgot that I didn't have any pages created on my desktop database. Embarrassing mistake lol.

Posted in Tabs with Stimulus

Oh never mind I am dumb. Figured it out.

Posted in Tabs with Stimulus

Hi Chris - I've been following your guide on adding tabs with Stimulus here: https://github.com/excid3/tailwindcss-stimulus-components

I am not using Tailwind but everything is working. However, when I add a block inside tab 1 nothing is rendered? The h2 content is rendered though.

There are no errors, so I am scratching my head.

example:

<div class="hidden dbroot__content--1" data-target="tabs.panel">
    <h2>This is tab 1</h2>
    <div class="whatever">
    <% @pages.each do |page| %>
         <%= page.title %>
         <%= page.slug %>
         <%= link_to 'Show', page %>
         <%= link_to 'Edit', edit_dashboard_page_path(page) %>
         <%= link_to 'Destroy', page, method: :delete, data: { confirm: 'Are you sure?' } %>
      </tr>
    <% end %>
    </div>

No affect, unfortunately. No form errors are displayed if I try and update with a blank email or name.

Hey Chris - I have a follow-up question on the above issue if you don't mind.

My current set up allows users to edit their password in the traditional way, but in my dashboard/users controller, I want users to be able to update their profile, i.e. their name, email, bio, etc without a password.

This all works, but if a user fails to enter their email or name, no validation errors are displayed. I believe that Devise considers an empty field as no change, from what I can gather from the terminal output.

Is there a way to show the errors or am I going about this the wrong way?

Users Controller

module Dashboard
  class UsersController < DashboardsController
    before_action :set_user, only: [:show, :edit, :update, :destroy]
    before_action :check_admin, only: [:index]

    layout 'dashboard'

    def index
      @users = User.all
    end

    def show
    end

    def edit
    end

    def update
      if @user.update(user_params) 
       bypass_sign_in(@user)
       redirect_to dashboard_user_path(@user)
       flash[:success] = t('dashboard_pages.users_controller.messages.update_success')
     else
       render :edit
     end
    end

    def destroy
      @user.destroy
      redirect_back(fallback_location: dashboard_root_path)
      flash[:success] = t('dashboard_pages.users_controller.messages.user_deleted')
    end

    private

    def set_user
      @user = User.friendly.find(params[:id])
    end

    def user_params
      params.require(:user).permit(:username, :email, :name, :role, :about, :slug, :img)
    end


  end
end

Form partial

<%= form_with(model: [ :dashboard, @user ]) do |f| %>
<%= render partial: 'shared/form_errors', locals: {obj: @user} %>

Errors partial

<% if obj.errors.any? %>
  <div id="error_explanation">
    <h4 class="white"><%= pluralize(obj.errors.count, "error") %> prohibited this about from being saved:</h2>

    <ul class="devise__errors">
      <% obj.errors.full_messages.each do |message| %>
        <li class="white devise__errors--list"><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

routes

namespace :dashboard do
        root to: 'dashboards#index'
        resources :dashboards, only: [:index]
        resources :users
devise_for :users, path: '', path_names: {edit: 'user_edit', new: 'new', sign_up: 'register', sign_in: 'login', sign_out: 'signed-out', password: 'secret', confirmation: 'verification', unlock: 'unlock', invitation: 'invite', verification: 'verification', remove: 'remove', accept: 'accept' }, controllers: { omniauth_callbacks: 'users/omniauth_callbacks', registrations: 'users/registrations', masquerades: 'users/masquerades', invitations: 'users/invitations' }
get 'signed-out', to: 'signouts#index'

Ah I am dumb, I got it working. Forgot that I needed to add the admin module in my form.

<%= form_for ["admin", @user] do |f| %>

Thank you for the quick reply.

Hey Chris - Do you have a best practices guide for server maintenance?
Brian

Posted in Nested Comment Threads in Rails - Part 1 Discussion

Woohoo, thanks for doing this!

Posted in Comments With Polymorphic Associations Discussion

That would be awesome. Thanks!

Posted in Comments With Polymorphic Associations Discussion

It would great if you could expand this to include comment replies. There are no great tutorials on how to accomplish this task.

Posted in Paypal & Stripe

I guess I am just not understanding how to change it from a subscription to a plan.

I am also currently using a developement url not a production one for my webhooks.

irb(main):001:0> e = Stripe::Event.retrieve("evt_1D3oX72OobZT8tZuFcNxXcpk")
=> #<Stripe::Event:0x2b1cb2657800 id=evt_1D3oX72OobZT8tZuFcNxXcpk> JSON: {
  "id": "evt_1D3oX72OobZT8tZuFcNxXcpk",
  "object": "event",  "api_version": "2018-05-21",
  "created": 1535390985,  "data": {"object":{"id":"sub_DUo9TmZzClFG1N","object":"subscription","application_fee_percent":null,"billing":"charge_automatically","billing_cycle_anchor":1535390983,"cancel_at_period_end":false,"canceled_at":null,"created":1535390983,"current_period_end":1538069383,"current_period_start":1535390983,"customer":"cus_DT7O4lor9yOHge","days_until_due":null,"discount":null,"ended_at":null,"items":{"object":"list","data":[{"id":"si_DUo92aCIKDATBh","object":"subscription_item","created":1535390984,"metadata":{},"plan":{"id":"monthly","object":"plan","active":true,"aggregate_usage":null,"amount":1900,"billing_scheme":"per_unit","created":1534660009,"currency":"cad","interval":"month","interval_count":1,"livemode":false,"metadata":{},"nickname":"Monthly","product":"prod_DRdeH2Q4y35faL","tiers":null,"tiers_mode":null,"transform_usage":null,"trial_period_days":null,"usage_type":"licensed"},"quantity":1,"subscription":"sub_DUo9TmZzClFG1N"}],"has_more":false,"total_count":1,"url":"/v1/subscription_items?subscription=sub_DUo9TmZzClFG1N"},"livemode":false,"metadata":{},"plan":{"id":"monthly","object":"plan","active":true,"aggregate_usage":null,"amount":1900,"billing_scheme":"per_unit","created":1534660009,"currency":"cad","interval":"month","interval_count":1,"livemode":false,"metadata":{},"nickname":"Monthly","product":"prod_DRdeH2Q4y35faL","tiers":null,"tiers_mode":null,"transform_usage":null,"trial_period_days":null,"usage_type":"licensed"},"quantity":1,"start":1535390983,"status":"active","tax_percent":null,"trial_end":null,"trial_start":null}},
  "livemode": false,
  "pending_webhooks": 1,
  "request": {"id":"req_jreFxqxCqmXk5P","idempotency_key":null},
  "type": "customer.subscription.created"
}
irb(main):002:0> Webhooks::ChargeSucceeded.new.call(e)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."stripe_id" = $1 LIMIT $2  [["stripe_id", "cus_DT7O4lor9yOHge"], ["LIMIT", 1]]
  Charge Load (0.2ms)  SELECT  "charges".* FROM "charges" WHERE "charges"."user_id" = $1 AND "charges"."stripe_id" = $2 ORDER BY "charges"."id" ASC LIMIT $3  [["user_id", 9], ["stripe_id", "sub_DUo9TmZzClFG1N"], ["LIMIT", 1]]
   (0.1ms)  BEGIN
  Charge Create (33.9ms)  INSERT INTO "charges" ("user_id", "stripe_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["user_id", 9], ["stripe_id", "sub_DUo9TmZzClFG1N"], ["created_at", "2018-08-27 22:52:08.728957"], ["updated_at", "2018-08-27 22:52:08.728957"]]
   (7.2ms)  COMMIT
Traceback (most recent call last):
        2: from (irb):2
        1: from app/models/webhooks/charge_succeeded.rb:10:in `call'
NoMethodError (undefined method `amount' for #<Stripe::Subscription:0x00005639687c59c8>)

Inside of Stripe

Webhooks
Pending
http://localhost:3000/webhooks/stripe
Status
503 Pending (5 tries)
Retry history
[2018/08/27 11:29 to http://localhost:3000]: (503) ERR
[2018/08/27 12:49 to http://localhost:3000]: (503) ERR
[2018/08/27 14:02 to http://localhost:3000]: (503) ERR
[2018/08/27 15:07 to http://localhost:3000/webhooks/stripe]: (503) ERR
[2018/08/27 15:47 to http://localhost:3000/webhooks/stripe]: (503) ERR
Request
{
  "id": "evt_1D3oX72OobZT8tZuFcNxXcpk",
  "object": "event",
  "api_version": "2018-05-21",
  "created": 1535390985,
  "data": {
    "object": {
      "id": "sub_DUo9TmZzClFG1N",
      "object": "subscription",
      "application_fee_percent": null,
      "billing": "charge_automatically",
      "billing_cycle_anchor": 1535390983,
      "cancel_at_period_end": false,
      "canceled_at": null,
      "created": 1535390983,
      "current_period_end": 1538069383,
      "current_period_start": 1535390983,
      "customer": "cus_DT7O4lor9yOHge",
      "days_until_due": null,
      "discount": null,
      "ended_at": null,
      "items": {
        "object": "list",
        "data": [
          {
            "id": "si_DUo92aCIKDATBh",
            "object": "subscription_item",
            "created": 1535390984,
            "metadata": {
            },
            "plan": {
              "id": "monthly",
              "object": "plan",
              "active": true,
              "aggregate_usage": null,
              "amount": 1900,
              "billing_scheme": "per_unit",
              "created": 1534660009,
              "currency": "cad",
              "interval": "month",
              "interval_count": 1,
              "livemode": false,
              "metadata": {
              },
              "nickname": "Monthly",
              "product": "prod_DRdeH2Q4y35faL",
              "tiers": null,
              "tiers_mode": null,
              "transform_usage": null,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "quantity": 1,
            "subscription": "sub_DUo9TmZzClFG1N"
          }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "/v1/subscription_items?subscription=sub_DUo9TmZzClFG1N"
      },
      "livemode": false,
      "metadata": {
      },
      "plan": {
        "id": "monthly",
        "object": "plan",
        "active": true,
        "aggregate_usage": null,
        "amount": 1900,
        "billing_scheme": "per_unit",
        "created": 1534660009,
        "currency": "cad",
        "interval": "month",
        "interval_count": 1,
        "livemode": false,
        "metadata": {
        },
        "nickname": "Monthly",
        "product": "prod_DRdeH2Q4y35faL",
        "tiers": null,
        "tiers_mode": null,
        "transform_usage": null,
        "trial_period_days": null,
        "usage_type": "licensed"
      },
      "quantity": 1,
      "start": 1535390983,
      "status": "active",
      "tax_percent": null,
      "trial_end": null,
      "trial_start": null
    }
  },
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": "req_jreFxqxCqmXk5P",
    "idempotency_key": null
  },
  "type": "customer.subscription.created"
}
Response
host localhost:3000 resolves to illegal IP 127.0.0.1
logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2020 GoRails, LLC. All rights reserved.