-
Notifications
You must be signed in to change notification settings - Fork 69
Acceptance between administrators #790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: time-between-banks-base
Are you sure you want to change the base?
Acceptance between administrators #790
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- db/structure.sql: Language not supported
config/locales/es.yml
Outdated
actions: "Acciones" | ||
sent: "Enviadas" | ||
received: "Recibidas" | ||
pending: "Pending" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Spanish translation for 'pending' remains in English. Consider updating it (e.g., to 'Pendiente' or a more context-appropriate term) for consistency.
pending: "Pending" | |
pending: "Pendiente" |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmartincor I think our Our colleague Copilot is right
target_organization_id: params[:organization_alliance][:target_organization_id], | ||
status: "pending" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the create action, the target_organization_id is accessed directly from params instead of using the alliance_params method. Consider refactoring to use strong parameters (alliance_params) to enhance consistency and security.
target_organization_id: params[:organization_alliance][:target_organization_id], | |
status: "pending" | |
target_organization_id: alliance_params[:target_organization_id], |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmartincor another point for Copilot
Hi @gmartincor , I've been a bit busy lately and I continue busy, so I'll be slow in the PRs review, sorry for that 🙏. Thanks for the contribution! |
@@ -5,24 +5,20 @@ | |||
it "validates content_type" do | |||
temp_file = Tempfile.new('test.txt') | |||
organization.logo.attach(io: File.open(temp_file.path), filename: 'test.txt') | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert this change since it only generates
expect(organization).to be_invalid | ||
|
||
temp_file = Tempfile.new('test.svg') | ||
organization.logo.attach(io: File.open(temp_file.path), filename: 'test.svg') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
expect(organization).to be_invalid | ||
|
||
temp_file = Tempfile.new('test.png') | ||
organization.logo.attach(io: File.open(temp_file.path), filename: 'test.png') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
expect(organization).to be_valid | ||
end | ||
end | ||
|
||
describe '#display_id' do | ||
subject { organization.display_id } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
end | ||
|
||
def create | ||
@alliance = OrganizationAlliance.new( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no need for @
ivar here I think
end | ||
|
||
def update | ||
authorize @alliance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we have before_action :authorize_admin
we don't need an authorize
here
end | ||
|
||
def destroy | ||
authorize @alliance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
unless current_user.manages?(current_organization) | ||
flash[:error] = t("organization_alliances.not_authorized") | ||
redirect_to root_path | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this code could be prettier using a guard clause:
if current_user.manages?(current_organization) return
flash[:error] = t("organization_alliances.not_authorized")
redirect_to root_pat
app/models/organization.rb
Outdated
has_many :source_alliances, class_name: "OrganizationAlliance", foreign_key: "source_organization_id", dependent: :destroy | ||
has_many :target_alliances, class_name: "OrganizationAlliance", foreign_key: "target_organization_id", dependent: :destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this naming is clear enough, maybe:
initiated_alliances / received_alliances
outgoing_alliances / incoming_alliances
what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I´m agree with you, I have changed source_alliances by source_alliances and target_alliances by received_alliances.
Thank you very much for your advice @franpb14 :)
app/models/organization.rb
Outdated
def pending_sent_alliances | ||
source_alliances.pending | ||
end | ||
|
||
def pending_received_alliances | ||
target_alliances.pending | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not combine this with an or
like the other 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented your suggestion to combine the methods for pending alliances using the or
operator, just like we do with accepted and rejected alliances.
To make this change, I not only modified the Organization
model by creating the pending_alliances method
, but I also updated the controller organization_alliances_controller
to use this new method:
# Before:
current_organization.pending_sent_alliances.includes(:source_organization, :target_organization) +
current_organization.pending_received_alliances.includes(:source_organization, :target_organization)
# After:
current_organization.pending_alliances.includes(:source_organization, :target_organization)
alliance = record | ||
user.manages?(alliance.source_organization) || user.manages?(alliance.target_organization) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to understand, why do we need this? and also this repeated code could be an auxiliar function
<div class="row"> | ||
<div class="col-12 col-sm-12 col-md-12 col-lg-12"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
col-12 is enough, since you are not giving other sizes
<% if is_sender %> | ||
<%= t('organization_alliances.sent') %> | ||
<% else %> | ||
<%= t('organization_alliances.received') %> | ||
<% end %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be just this:
<%= t("organization_alliances.#{is_sender ? 'sent' : 'received'}'") %>
<% is_sender = (alliance.source_organization_id == current_organization.id) %> | ||
<% other_org = is_sender ? alliance.target_organization : alliance.source_organization %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this code to a helper, the views should have the less ruby code as possible
db/structure.sql
Outdated
@@ -1,25 +1,13 @@ | |||
SET statement_timeout = 0; | |||
SET lock_timeout = 0; | |||
SET idle_in_transaction_session_timeout = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in this whole file there a bunch of changes not related with your migration and it could break, probably because the database version, make sure you only leave what's important and don't change anything else.
let!(:pending_sent) { | ||
OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: other_organization, | ||
status: "pending" | ||
) | ||
} | ||
|
||
let!(:pending_received) { | ||
OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: organization, | ||
status: "pending" | ||
) | ||
} | ||
|
||
let!(:accepted) { | ||
OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: Fabricate(:organization), | ||
status: "accepted" | ||
) | ||
} | ||
|
||
let!(:rejected) { | ||
OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: Fabricate(:organization), | ||
status: "rejected" | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use these let at the beggining, create a fabricator for this model and if the ! after let is not needed don't use it
end | ||
|
||
it "sets flash error if alliance cannot be created" do | ||
# Try to create alliance with self which is invalid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not use comments for that, it is already described in the test
let!(:alliance) { | ||
OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: organization, | ||
status: "pending" | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same move this to the beggining
let!(:alliance) { | ||
OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: other_organization | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, you probably will be able to reuse some
let(:other_organization) { Fabricate(:organization) } | ||
|
||
around do |example| | ||
I18n.with_locale(:en) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strange, I'm not sure about this
@pending_alliance = OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: other_organization, | ||
status: "pending" | ||
) | ||
|
||
@accepted_alliance = OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: Fabricate(:organization), | ||
status: "accepted" | ||
) | ||
|
||
@rejected_alliance = OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: Fabricate(:organization), | ||
status: "rejected" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should be let at the beggining
alliance = OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: other_organization | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same use the fabricator at the beginning in this file
@pending_sent = OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: other_organization, | ||
status: "pending" | ||
) | ||
|
||
@pending_received = OrganizationAlliance.create!( | ||
source_organization: third_organization, | ||
target_organization: organization, | ||
status: "pending" | ||
) | ||
|
||
@accepted_sent = OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: Fabricate(:organization), | ||
status: "accepted" | ||
) | ||
|
||
@accepted_received = OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: organization, | ||
status: "accepted" | ||
) | ||
|
||
@rejected_sent = OrganizationAlliance.create!( | ||
source_organization: organization, | ||
target_organization: Fabricate(:organization), | ||
status: "rejected" | ||
) | ||
|
||
@rejected_received = OrganizationAlliance.create!( | ||
source_organization: Fabricate(:organization), | ||
target_organization: organization, | ||
status: "rejected" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
I think that's all for now, I'd like to give it a second go when it's all fixed 😄 |
2687a1a
to
13cd2c4
Compare
grabacion-de-pantalla-2025-04-14-a-las-92316_CkLB7uBF.1.mp4
Alliance Feature for Time Banks
This new feature that allows time banks to establish alliances with each other. This functionality extends the existing organization relationship model to enable time banks to collaborate more effectively.
The implementation includes:
A migration to create the
organization_alliances
table which tracks relationships between time banks.Only organization administrators can manage alliances.New models and controllers to manage the alliance lifecycle (request, accept/reject, end alliance).
UI components integrated into the existing organizations views, allowing administrators to:
Several tests to ensure the functionality works as expected.