I'm developing a project with Rails and I need help at this point.
mercredi 30 juin 2021
vendredi 25 juin 2021
Action Cable Signaling Server not working on different networks
I have an issue with my Ruby on rails 6 app. I make a video chat app with signaling-server js (WebRTC JS) and action-cable. video chat working fine on the same network in production. but it's not working on a different network. connection is established but video not streaming. it's not showing some error.
signaling_server.js file.
import consumer from "./channels/consumer";
// Broadcast Types
const JOIN_ROOM = "JOIN_ROOM";
const EXCHANGE = "EXCHANGE";
const REMOVE_USER = "REMOVE_USER";
// DOM Elements
let currentUser;
let localVideo;
let remoteVideoContainer;
let user;
// Objects
let pcPeers = {};
let localstream;
window.onload = () => {
user = document.getElementById("current-user");
if(user) {
currentUser = document.getElementById("current-user").innerHTML;
localVideo = document.getElementById("local-video");
remoteVideoContainer = document.getElementById("remote-video-container");
}
};
// Ice Credentials
const ice = { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] };
// Add event listener's to buttons
document.addEventListener("DOMContentLoaded", () => {
const joinButton = document.getElementById("join-button");
const leaveButton = document.getElementById("leave-button");
joinButton.onclick = handleJoinSession;
leaveButton.onclick = handleLeaveSession;
});
// Initialize user's own video
document.onreadystatechange = () => {
if (document.readyState === "interactive") {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.then((stream) => {
localstream = stream;
localVideo.srcObject = stream;
localVideo.muted = true;
})
.catch(logError);
}
};
const handleJoinSession = async () => {
consumer.subscriptions.create("VideoSessionChannel", {
connected: () => {
broadcastData({
type: JOIN_ROOM,
from: currentUser,
});
},
received: (data) => {
console.log("received", data);
if (data.from === currentUser) return;
switch (data.type) {
case JOIN_ROOM:
return joinRoom(data);
case EXCHANGE:
if (data.to !== currentUser) return;
return exchange(data);
case REMOVE_USER:
return removeUser(data);
default:
return;
}
},
});
};
const handleLeaveSession = () => {
for (let user in pcPeers) {
pcPeers[user].close();
}
pcPeers = {};
consumer.unsubscribe();
remoteVideoContainer.innerHTML = "";
broadcastData({
type: REMOVE_USER,
from: currentUser,
});
};
const joinRoom = (data) => {
createPC(data.from, true);
};
const removeUser = (data) => {
console.log("removing user", data.from);
let video = document.getElementById(`remoteVideoContainer+${data.from}`);
video && video.remove();
delete pcPeers[data.from];
};
const createPC = (userId, isOffer) => {
let pc = new RTCPeerConnection(ice);
pcPeers[userId] = pc;
console.log('createPC');
// for (const track of localstream.getTracks()) {
// pc.addTrack(track, localstream);
// }
pc.addStream(localstream);
isOffer &&
pc
.createOffer()
.then((offer) => {
console.log('createPC createOffer');
return pc.setLocalDescription(offer);
})
.then(() => {
broadcastData({
type: EXCHANGE,
from: currentUser,
to: userId,
sdp: JSON.stringify(pc.localDescription),
});
})
.catch(logError);
pc.onicecandidate = (event) => {
event.candidate &&
broadcastData({
type: EXCHANGE,
from: currentUser,
to: userId,
candidate: JSON.stringify(event.candidate),
});
};
pc.onaddstream = (event) => {
console.log(event.stream);
const element = document.createElement("video");
element.id = `remoteVideoContainer+${userId}`;
element.autoplay = "autoplay";
element.srcObject = event.stream;
remoteVideoContainer.appendChild(element);
};
pc.oniceconnectionstatechange = () => {
if (pc.iceConnectionState == "disconnected") {
console.log("Disconnected:", userId);
broadcastData({
type: REMOVE_USER,
from: userId,
});
}
};
return pc;
};
const exchange = (data) => {
let pc;
if (!pcPeers[data.from]) {
pc = createPC(data.from, false);
} else {
pc = pcPeers[data.from];
}
if (data.candidate) {
pc.addIceCandidate(new RTCIceCandidate(JSON.parse(data.candidate)))
.then(() => console.log("Ice candidate added"))
.catch(logError);
}
if (data.sdp) {
const sdp = JSON.parse(data.sdp);
pc.setRemoteDescription(new RTCSessionDescription(sdp))
.then(() => {
if (sdp.type === "offer") {
pc.createAnswer()
.then((answer) => {
console.log('exchange createAnswer');
return pc.setLocalDescription(answer);
})
.then(() => {
broadcastData({
type: EXCHANGE,
from: currentUser,
to: data.from,
sdp: JSON.stringify(pc.localDescription),
});
});
}
})
.catch(logError);
}
};
const broadcastData = (data) => {
/**
* Add CSRF protection: https://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in-javascript
*/
const csrfToken = document.querySelector("[name=csrf-token]").content;
const headers = new Headers({
"content-type": "application/json",
"X-CSRF-TOKEN": csrfToken,
});
fetch("sessions", {
method: "POST",
body: JSON.stringify(data),
headers,
});
};
const logError = (error) => console.warn("Whoops! Error:", error);
routes.rb file
mount ActionCable.server, at: "/cable"
Video Sessions Controller
class VideoSessionsController < ApplicationController
def create
head :no_content
ActionCable.server.broadcast "video_session_channel", session_params
end
private
def session_params
params.require(:video_session).permit(:type, :from, :to, :sdp, :candidate)
end
end
video channel file
class VideoSessionChannel < ApplicationCable::Channel
def subscribed
stream_from "video_session_channel"
end
end
video chat HTML file.
<span id="current-user"><%= @random_number %></span>
<div class="video-chat-content">
<div class="" id="remote-video-container"> </div>
<video id="local-video" autoplay></video>
</div>
lundi 21 juin 2021
How to query in database with GraphQL where to pluck only selected fields not all fields?
I want to know if we can query to pluck selected columns and the request to the database to search for only those selected columns not the whole data at the endpoint. If there is any confusion in this question please let me know.
dimanche 20 juin 2021
Byebug does not pauses in controller in RSpec request spec
I have added byebug
breakpoint in spec code and it pauses the code there.
require 'rails_helper'
RSpec.describe "UsedCars", :type => :request do
describe "POST /used_cars" do
it "creates a used car ad" do
byebug # <- stop here
count = UsedCar.count
post used_cars_path, used_car: attributes_for(:used_car)
expect(UsedCar.count).to eq(count + 1)
end
end
end
But when I add the breakpoint in the controller-action method of the request being tested. it does not stop there. I have even tried it in the top-level before_filter for application_controller.
app/controllers/used_car_controller.rb
def create
byebug # <- does not stop here
....
end
Even in the application_controller.rb
# top before_filter
before_fitler :stop
...
def stop
byebug # does not even stop here
end
I am using Rails 3 with ruby 2.2.8
samedi 19 juin 2021
rake aborted while creating admin user
I am using ubuntu 18.4, Ruby 2.7.3 , rails 4.2.11.1, Rake 10.0.0
While trying to run the rake admin:create
, I am getting the below error message. Can any one help me on this.
/home/ubuntu/.rbenv/versions/2.7.3/lib/ruby/2.7.0/uri/version.rb:3: warning: already initialized constant URI::VERSION_CODE
/home/ubuntu/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/uri-0.10.1/lib/uri/version.rb:3: warning: previous definition of VERSION_CODE was here
/home/ubuntu/.rbenv/versions/2.7.3/lib/ruby/2.7.0/uri/version.rb:4: warning: already initialized constant URI::VERSION
vendredi 18 juin 2021
How to set secure flag to active_record_store cookies
I have set cookies to store them in active_record. And followed the documentation from guides.rubyonrails and suggestions from similar case but with no luck. So far I have this in my config/initializers/session_store.rb:
Application.config.session_store :active_record_store,
:expire_after => 1.weeks.to_i,
:key => '_webapp_session',
secure: Rails.env.production?
and my cookies stay insecure.
jeudi 17 juin 2021
How to stop at a specific range in ruby loops
i have this piece of code here that generates a link for all of my questions from a database, but right now I have 10 entries and this loop will iterate 10 times. Is there a way to stop the iteration at a range of 4?
<table>
<tr>
<th>Question</th>
<th>Button</th>
</tr>
</tr>
<% @questions.each do |q| %>
<tr>
<td><%= q.question %></td>
<td><%= link_to 'Question', show_url(q.id), method: :get %></td>
<td><%= q.id %> Button</td>
<% end %>
</tr>
</table>
Any suggestions will be appreciated! Thanks.
Swiper js pagination not showing up in my ruby on rails project
My code :
- application.js
const mySwiper = new Swiper('.swiper-container', { spaceBetween: 16, loop: false, grabCursor: true, pagination: { el: '.swiper-pagination', clickable: true, }, breakpoints: { 640: { slidesPerView: 2, }, 1024: { slidesPerView: 3, }, } }) }
js imports js improrts
2.html
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
</div>
<div class="swiper-pagination"></div>
</div>
imported it into the application.scss
dimanche 13 juin 2021
How to display a calculation in Ruby?
I am trying to display a simple calculation for how much gas one may need for a trip. I have my logic in my view for now so that I can easily display the value. Here is the form the user fills out:
<h1>New Trip!</h1>
<br>
<br>
<%= f.label :title %>
<%= f.text_field :title %>
<br>
<br>
<%= f.label :content %>
<%= f.text_area :content %>
<br>
<br>
<%= f.label :mileage %>
<%= f.number_field :mileage, step: :any %>
<br>
<br>
<%= f.label :mpg %>
<%= f.number_field :mpg, step: :any %>
<br>
<br>
<%= f.label :amount %>
<%= f.number_field :amount, step: :any %>
<%= f.submit %>
<% end %>
<% end %>
I would like to have the value of this calculation displayed next to the roadtrip they created. Here is what I have in my partial view that displays the user's trips:
<ul>
<% roadtrips.each do |r| %>
<li><%= link_to r.title, roadtrip_path(r) %> - <%= r.name%> </li>%
<p><%= (r.mileage / r.mpg)*2.90 %></p>
<% end %>
</ul>
When I go to create the trip and click submit I do get a nil error on '/' not sure why because I thought that's how you divide in Ruby.
Any feedback/suggestions would be greatly appreciated. Thanks in advanced!
samedi 12 juin 2021
How to Get Both Coordinates In a Nested Array?
I'm working on a chess game and want to search the nested array for the King piece K(b)
and then return the coordinates.
I've tried the following method which returns 4 (the x coordinate - the index in the internal array). However, I'm trying to figure out how to also return index of the outer array. Expected output is [4, 7]
:
piece = "K(b)"
def coordinates_for_piece(piece)
@board.map { |item| item.find_index(piece) }
end
Board:
def piece_setup
@board = Array.new(8) { Array.new([" . ", " . ", " . ", " . ", " . ", " . ", " . ", " . "]) }
@board[0] = ["R(w)", "N(w)", "B(w)", "Q(w)", "K(w)", "B(w)", "N(w)", "R(w)"]
@board[1] = ["P(w)", "P(w)", "P(w)", "P(w)", "P(w)", "P(w)", "P(w)", "P(w)"]
@board[6] = ["P(b)", "P(b)", "P(b)", "P(b)", "P(b)", "P(b)", "P(b)", "P(b)"]
@board[7] = ["R(b)", "N(b)", "B(b)", "Q(b)", "K(b)", "B(b)", "N(b)", "R(b)"]
end
EDIT: This is a VERY clunky way of accomplishing the goal. Looking for something more streamlined.
def coordinates_for_piece(piece)
test = @board.map { |item| item.find_index(piece) }
=> [nil, nil, nil, nil, nil, nil, nil, 4]
x = test.find{|x| !x.nil?}
=> 4
y = test.find_index{|y| !y.nil?}
=> 7
[x, y]
end
jeudi 10 juin 2021
Create a image with MiniMagick::Image getting improper image header
I'm creating a png
image with MiniMagick::Image
and it giving me an false result when I checked with valid?
function: there are 2 error composite: ImproperImageHeader
and composite: MissingAnImageFilename
Here is my code:
img = MiniMagick::Image.new(Tempfile.new(['label_creation_date', '.png']).path)
MiniMagick::Image.new(Tempfile.new(['label_creation_date', '.png']).path).tap do |tmp_image|
MiniMagick::Tool::Convert.new.tap do |convert|
convert << tmp_image.path
convert.background 'transparent'
convert.rotate '-4'
convert << tmp_image.path.to_s
end
end
I tried one more solution that in gives in https://github.com/minimagick/minimagick/issues/59#issuecomment-3775000 here, but unfortunately it's also not working.
Please help me how can I create a valid image from scratch with the help of minimagick
?
Thanks
mardi 8 juin 2021
rails_admin gem auto sorting when stored as an array
I am using rails_admin gem
I am saving data in the form of array . The data is being stored.
I am facing an issue while editing the data. While editing and saving the data the array is auto sorting. I haven't written any sort array function.
How can I stop the auto sortarray while saving
Thank you
dimanche 6 juin 2021
Error: port 22: Resource temporarily unavailable in wsl
I am using capistrano gem to deploy my rails app on ec2 instance and i am facing Error: port 22: Resource temporarily unavailable in wsl.
I have tried the following things but facing the same problem still:
- eval
ssh-agent -s
- Added inbound and outbound rule
I am not able to figure out the problem now
samedi 5 juin 2021
Improving a query. One book for each author
I need an hand to improve this query
def interesting_books
Book.joins(:genre)
.where(author: interesting_authors.sample(5))
.where('ratings >= 4')
.random_order
.where.not(id: black_books)
.limit(3)
end
def interesting_authors
@interesting_authors ||= (authors_commented_books + authors_watched_books).uniq
end
def authors_commented_books
@authors_commented_books ||= current_user.commented_books.pluck(:author).uniq
end
def authors_watched_books
@authors_watched_books ||= current_user.watched_books.pluck(:author).uniq
end
now, in this way if in the .where(author: interesting_authors.sample(5))
i have authors like "Shakespear", "Twain" , "Fitzgerald", "Wilde" and "Darwin"... it shows only 3 books (.limit(3)) made by "Shakespear". Result: "Macbeth", "Othello" and "The Tempest".
BUT I want to show 3 books made by different (selected) authors. Like "Othello", "The Great Gatsby" and "Dorian Gray".
How to do?
vendredi 4 juin 2021
bundle install is failed on windows for ruby
Please Im trying to run bundle install but its not finished and I got that error: city.cc:91:10: fatal error: byteswap.h: No such file or directory, it said Make sure that `gem install cityhash -v '0.9.0', i did that but i got the same error saying it can't install cityhash. enter image description here
How to extract from an array of hash
people = [
{id: 101, first_name: 'John', last_name: 'Doe'},
{id: 102, first_name: 'Tom', last_name: 'Rogers'},
{id: 103, first_name: 'Bill', last_name: ''}
]
I want to put a list of name like this, "John Doe, Tom Rogers, Bill"
How can i achieve this is in ruby?