Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [inny]Laravel problem z rolami użytkownika, nie bierze pod uwagę warunku
casperii
post 27.09.2020, 13:28:05
Post #1





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


Panowie, przejdę może od razu do rzeczy, mam kod:

Role.php :
  1. <?php
  2.  
  3. namespace App;
  4.  
  5. use Illuminate\Database\Eloquent\Model;
  6.  
  7. class Role extends Model
  8. {
  9.  
  10. public $guarded = [];
  11. public $timestamps = false;
  12.  
  13. public function users()
  14. {
  15. return $this->belongsToMany('App\User');
  16. }
  17. }


oraz RegisterController.php

  1. if(!Role::where('name','type')->exists())
  2. {
  3. Role::create(['name'=>'person']);
  4. Role::create(['name'=>'firm']);
  5. }
  6.  
  7. //sprawdzamy czy typ = 0 czyli równy 1 - jeżeli tak dodaje Role firm w innym przypadku dodaje person w tabeli roles
  8.  
  9. if($data['type'] questionmark.gif 0)
  10. $user->roles()->attach( Role::where('name','firm')->first()->id );
  11. else
  12. $user->roles()->attach( Role::where('name','person')->first()->id );
  13.  


czyli przy każdej rejestracji użytkownika dodaje także do tabeli role_user typ konta (firma / os. fiz) , oraz dodatkowo mam stworzony warunek , który nie działa zgodnie z jego logiką, tzn. sprawdzam czy istnieje w tabeli roles jakieś pola , jeżeli nie to dopisuje 2 rekordy person oraz firm. Problem w tym, że warunek ten działa zawsze bez znaczenia czy ów wartości znajdują się już w tabeli czy też nie.

Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 16:45:22
Post #2





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Jakiś dziwny ten Twój kod. Sprawdzasz, czy istnieje rola z kolumną *name* o wartości *type*? Tak po prostu, bez względu na przypisania do użytkownika?

Po drugie nie pokazałeś tego $data i nie powiedziałeś o którym warunku mówisz. Napisz jaśniej i pokaż więcej kodu.

Poza tym, firma to po angielsku company, a nie firm tongue.gif

Ten post edytował SmokAnalog 27.09.2020, 16:46:32
Go to the top of the page
+Quote Post
casperii
post 27.09.2020, 20:03:24
Post #3





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


@SmokAnalog odnośnie twojej uwagi:
They are almost the same, but "firm" is often used for legal type businesses. "Company" is more common.

co do kodu :
  1. protected function create(array $data)
  2. {
  3. $user = User::create(
  4. [
  5. 'user' => $data['user'],
  6. 'email' => $data['email'],
  7. 'password' => bcrypt($data['password']),
  8. 'ip' => request()->ip(),
  9. 'key' => Uuid::generate()->string,
  10. ]
  11. );
  12.  
  13.  
  14. if(!Role::where('name','type')->exists())
  15. {
  16. Role::create(['name'=>'person']);
  17. Role::create(['name'=>'firm']);
  18. }
  19.  
  20. //sprawdzamy czy typ = 0 czyli równy 1 - jeżeli tak dodaje Role firm w innym przypadku dodaje person w tabeli roles
  21.  
  22. if($data['type'] questionmark.gif 0)
  23. $user->roles()->attach( Role::where('name','firm')->first()->id );
  24. else
  25. $user->roles()->attach( Role::where('name','person')->first()->id );
  26.  
  27.  
  28. return $user;
  29. }
  30.  
  31.  
  32. public function register(Request $request)
  33. {
  34. $this->validator($request->all())->validate();
  35. $user = $this->create($request->all());
  36.  
  37. event(new Registered($user));
  38. $this->guard()->login($user);
  39. UserVerification::generate($user);
  40. UserVerification::send($user, 'Potwierdzenie rejestracji konta.', env('MAIL_FROM_ADDRESS'), env('APP_NAME'));
  41.  
  42. /* wiadomość znajduje się w isVerified*/
  43.  
  44. return $this->registered($request, $user)
  45. ?: redirect($this->redirectPath());
  46. }


Mam 3 tabele : users , roles, role_user,

users - wiadomo
tabela roles:
id, name
1, person
2, firm

oraz trzecią tabele role_user
user_id, role_id
1, 1
2, 1
3, 2
4, 1
5, 2

czyli zamierzeniem / zabezpieczeniem kodu:
  1. if(!Role::where('name','type')->exists())


powinno być jeśli nie ma danych w tabeli roles , uzupełnij je danymi :
  1. Role::create(['name'=>'person']);
  2. Role::create(['name'=>'firm']);


Niestety każde dodanie nowego użytkownika powoduje, że w tabeli roles dane mi się dopisują tzn:
1, person
2, firm
3, peron
4, firm
5, person
6, firm

itd.
Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 20:54:53
Post #4





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Ale ta linia:

  1. if(!Role::where('name','type')->exists())


Nie oznacza, że nie ma danych w tabeli Roles, tylko że nie ma rekordu w tabeli roles, gdzie name = 'type'. Trochę bez sensu chyba?
Go to the top of the page
+Quote Post
casperii
post 27.09.2020, 21:19:07
Post #5





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


inaczej, przy stworzeniu pierwszego użytkownika zabezpieczam się przed tym by tabela roles miała już jakieś wartości.
kurde czemu dałem tam type a nie person (?)
  1. if(!Role::where('name','person')->exists())


i bangla smile.gif
Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 21:21:45
Post #6





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


A nie lepiej sprawdzić czy w ogóle są jakiekolwiek, zamiast zakładać, że ma być ta jedna? Moim zdaniem taki kod prosi się o trudne do znalezienia błędy w przyszłości.
Go to the top of the page
+Quote Post
casperii
post 27.09.2020, 21:23:09
Post #7





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


jakaś podpowiedź ? smile.gif
Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 21:27:03
Post #8





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Moim zdaniem lepiej byłoby po prostu tego nie sprawdzać, tylko mieć seedy do wstawiania tych podstawowych ról. Logika nie powinna się sypać, kiedy nie masz ról. Ewentualnie dałbym do panelu admina ostrzeżenie, gdy role są puste. Wiesz, warto unikać takich sprawdzajek, bo to niewiele wnosi, a dodaje warstwę logiki, o której się zapomina.
Go to the top of the page
+Quote Post
casperii
post 27.09.2020, 21:30:48
Post #9





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


oczywiście na dalszym planie jest możliwość dodawania / edytowania / usuwania ról z poziomu panelu administracyjnego. Nie mniej jednak dziękuje za sugestię

Ten post edytował casperii 27.09.2020, 21:47:15
Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 21:37:03
Post #10





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


No tak szczerze mówiąc to wstawianie ról przy wstawianiu użytkownika prosi się o problemy smile.gif To nie jest miejsce w kodzie, w którym chcesz cichaczem dodawać rekordy do innego modelu.

Gdybyś pytał, to żeby sprawdzić czy tabela zawiera jakiekolwiek rekordy, możesz dać exists() od razu, czyli:

  1. if (Role::exists()) {
Go to the top of the page
+Quote Post
casperii
post 27.09.2020, 21:46:59
Post #11





Grupa: Zarejestrowani
Postów: 680
Pomógł: 28
Dołączył: 14.08.2014

Ostrzeżenie: (0%)
-----


@SmokAnalog jeszcze mam pytanie odnośnie dodatkowych danych usera (imie, nazwisko , płeć, data ur, adres ... ) te dane będzie można dopiero dopisać po weryfikacji maila ( nie chcę usera zanudzać wypełnieniem pól)
czy lepiej dodać powyższe pola do tabeli user, czy np utworzyć inną tabelę i tam wstawiać te pola ?
Go to the top of the page
+Quote Post
SmokAnalog
post 27.09.2020, 21:55:20
Post #12





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Wiesz co, tak naprawdę to i tak, i tak będzie w porządku. Osobna tabela będzie miała taką zaletę, że możesz z poziomu bazy zadbać o integralność danych.

Konkretniej, to jest dobry przykład na użycie relacji 1:1. Dane byłyby połączone z użytkownikiem i user_id byłby unikalny. Kolumny w tej tabeli nie musiałyby być nullable. Mógłbyś też w jednoznaczny sposób się dowiedzieć, czy dany użytkownik wypełnił już swoje dane, czy nie. Świadczy o tym istnienie (lub brak) rekordu w tej dodatkowej tabeli.

Wadą takiego rozwiązania jest to, że przy domyślnym użyciu Eloquent, pojawiłby się oczywiście obiekt pośredni, czyli zamiast np. $user->name miałbyś np. $user->data->name. Trochę upierdliwe.

Ja bym chyba poszedł na skróty i dodał po prostu te kilka pól bezpośrednio do Usera w formie nullable. Integralność nie jest tak dobra, ale jest łatwiej ogarnąć dostęp do tych danych. Wtedy możesz wybrać jedną kolumnę jako dowód, że dane zostały już wypełnione, lub też wiele kolumn. Ja bym wstawił np. pole z datą wypełnienia danych (nullable) i tym się posługiwał przy ustalaniu czy ktoś wypełnił dane.

Ten post edytował SmokAnalog 27.09.2020, 21:56:27
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 24.04.2024 - 05:39