How can i update two fields in model at once?
Now i have request that return me an alias with {price: Float, productId: Int}
I need to update two fields in model like model.price and model.productId
I looking for something like that, but its not work (ofc)
case maybeProduct of
Just product ->
( { model | price = product.price &&
model | productId = product.productId}
, Cmd.none
)
Nothing ->
( model
, Cmd.none
)
I found some info where advice that I can create two functions
(Model -> Product -> Model) and do something like:
setPrice : Model -> Product -> Model
setPrice model product =
{ model | price = product.price }
setProductId : Model -> Product -> Model
setProductId model product =
{ model | companyId = product.productId }
Just product ->
let
newModel =
product
|> setPrice model
|> setProductId model
in
( newModel
, Cmd.none
)
Nothing ->
( model
, Cmd.none
)
but something dont work. It looks like product dont passing in each function
i recieve
The argument is:
Model
But (|>) is piping it a function that expects:
{ companyId : Int, price : Float }
Where i mistake? Or maybe there is different way to update two fields in model?
How to update two fields at once:
Do something like this (this excludes commands by the way - you can add that in to suit your requirements):
{ model | price = new_price, productId = newProductId}
If you want to add Commands then you can do this:
({ model | price = new_price, productId = newProductId}, nameOfYourCommand)
Documentation:
Here is a link that #JackLeow very kindly posted: https://elm-lang.org/docs/records#updating-records
Related
I am trying to access function parameters within the 'case' statement in that function and displaying data/"filtered" based on the permission flag..Is it possible?
Usecase: TypeCast the value based on the columnType and check if the user has the permission to view the column based on which you display either the value or say something like "filtered"
Here is what I tried
function rls_columnCheck
.create-or-alter function rls_columnCheck(tableName:string, columnName: string, value:string, columnType:string, IsInGroupPII:bool, IsInGroupFinance:bool) {
let PIIColumns = rls_getTablePermissions(tableName, "PII");
let FinanceColumns = rls_getTablePermissions(tableName, "Finance");
let val= case(columnType=="bool", tobool(value),
columnType=="datetime", todatetime(value),
columnType=="int", toint(value),
value);
iif(columnName in (PIIColumns),
iif(columnName in (FinanceColumns),
iif(IsInGroupPII == true and IsInGroupFinance == true,
val,
"filtered"), // PII True, Fin True
iif(IsInGroupPII == true,
val,
"filtered") // PII True, Fin False
),
iif(columnName in (FinanceColumns),
iif(IsInGroupFinance == true,
val,
"filtered"), // PII False, Fin True
val // PII False, Fin False
)
);
}
Error:
Call to iff(): #then data type (int) must match the #else data type (string)
val in your function must have a single and well-defined data type, that is known at "compile" time of the query.
you can't have different cases, where in each it has a different type (bool, datetime, int, string - in your case statement) - hence the error.
if it makes sense in your use case, you can try to always have val typed as string.
This is not a good approach to use RLS because this will actually cause the engine to run a function for every column of every record. It has many downsides:
Performance of displaying the table’s contents (even if you have full permissions)
Queries on the table won’t benefit from the indexes Kusto stores (suppose you query PermissionTesting2 | where Col1 has “blablabla” - instead of checking the index for “blablabla”, the engine will have to scan all the data, because it has to apply a function for every single cell)
A better approach is to do something like this:
let UserCanSeePII = current_principal_is_member_of('aadgroup=group1#domain.com');
let UserCanSeeFinance = current_principal_is_member_of('aadgroup=group2#domain.com');
let ResultWithPII = YourTable | where UserCanSeePII and (not UserCanSeeFinance) | where ... | extend ...;
let ResultWithFinance = YourTable | where UserCanSeeFinance and (not UserCanSeePII) | where ... | extend ...;
let ResultWithPIIandFinance = YourTable | where UserCanSeeFinance and UserCanSeePII | where ... | extend ...;
let ResultWithoutPIIandFinance = YourTable | where (not UserCanSeePII) and (not UserCanSeeFinance) | where ... | extend ...;
union ResultWithPII, ResultWithFinance, ResultWithPIIandFinance, ResultWithoutPIIandFinance
I want to search for users by user authority ,
Authority is 「general」「admin」,
α、 This code is search code
val states = proxy.vaultQueryBy<UserState>().states
val results = states.filter { it.state.data.authority.toString() == "general" }
β、This code is paging code
val paging = PageSpecification(1, 10)
val states = proxy.vaultQueryBy<UserState>(paging=paging).states
I want to use α and β at the same time
( I want to get the top 10 general users)
Is this possible? Thank you ,
It really should be as simple as:
val paging = PageSpecification(1, 10)
val states = proxy.vaultQueryBy<UserState>(paging=paging).states
val results = states.filter { it.state.data.authority.toString() == "general" }
Doesn't that work for you? If so what error are you seeing?
I have a simple case class MyContext(queries: Query) that I provide to the schema with : sangria.schema.Schema(deriveContextObjectType[MyContext, Query, Unit](_.queries)
MyQuery is a trait of Query
trait MyQuery {
#GraphQLField
def item(ctx: Context[MyContext, Unit])(id: String) ...
}
This works great. But what if I want to nest resolvers?
query {
item {
status # status is resolved from source B
price # price is resolved from source C
}
}
Is that possible to achieve? Would I return an ObjectType[Item] that has properties status and price annotated with #GraphQLField?
I think you can use deriveObjectType for an Item. It is also able to handle the #GraphQLField annotation (as an alternative you can also use IncludeMethods macro setting). Here is an example:
implicit val ItemType = deriveObjectType[MyContext, Item]()
Really appreciate #tenshi's answer! I tried using the deriveObjectType but was getting a type error:
type mismatch;
found : sangria.schema.Context[MyContext,Item]
required: sangria.schema.Context[MyContext,Unit]
But using deriveContextObjectType in conjunction with AddFields is working:
def schema = sangria.schema.Schema(
deriveContextObjectType[MyContext, Query, Unit](_.queries,
AddFields(
Field(
name = "item",
fieldType = deriveContextObjectType[MyContext, Item, Unit](_ => new Item),
resolve = _ => ()
)
))
)
And the Schema looks good, yielding:
type Query {
item: Item!
}
I have CLub model (clubs) hasMany with User model like
Club n-n User
and I have UserClub model with columns: id, club_id, user_id, etc
In Club model
public function getCountUsers()
{
return $this->hasMany(UserClub::className(), ['club_id'=>'id'])->count();
}
I wanna count all User on Club as code:
$query = Club::find()
->joinWith(['countUsers']);
// ->with('countUsers');
->all();
so it is not working and throwing an error
Club has no relation named \"countUsers\"."
Because it isn't a relation as it does not return a model object or an array of model objects, instead you are using ->count() that makes it return a string that contains the total count for the user against the club.
If you are looking to get a count for the users against all the Clubs you can use the currently defined relation like $club->countUser see below.
$clubs=Club::find()->all();
foreach($clubs as $club){
echo $club->countUser;
}
or change the relation to
public function getCountUser(){
return $this->hasMany(UserClub::className(), ['club_id'=>'id']);
}
and use it like
$clubs=Club::find()->all();
foreach($clubs as $club){
echo count($club->countUser);
}
or like below
$clubs=Club::find()->all();
foreach($clubs as $club){
echo $club->getCountUser()->count();
}
EDIT
You are actually trying to transform the following query using ActiveRecord as far as I understood from the discussion.
SELECT clubs.id, count(user_clubs.id) as total
FROM
clubs
left join user_clubs on clubs.id = user_clubs.club_id
group by clubs.id
if that is correct you can use the following
Clubs::find ()
->alias ( 'c' )
->select ( [ new \yii\db\Expression ( 'c.[[id]], count(uc.[[id]]) as total' ) ] )
->leftJoin ( '{{%user_clubs}} uc' , 'uc.club_id=c.id' )
->groupBy ( 'c.id' )
->all ();
Note : You have to do one more thing you have to add a public property $total inside your Club model and add it to safe rules, because you are selecting the count as an alias total and until unless you define it inside the model the result set won't show you the count, so add the following inside the Club model.
public $total;
under rules
[[other fields...,'total'] , 'safe' ] ,
EDIT2
For some reason, I have a feeling that you are trying to count by specifying a relation instead of specifying the ->leftJoin () with the table user_clubs in the query.
If that is so then you have to change your relation getUserCount() you should better give a meaningful name that describes it. i would rename it to getClubUsers()
public function getClubUsers(){
return $this->hasMany(UserClub::className(), ['club_id'=>'id']);
}
After this, you still have to declare a public property $total as I described before inside your Club model, and add it to safe rules.
Now you can write your query in the following way
Clubs::find ()
->alias ( 'c' )
->select ( [ new \yii\db\Expression ( 'c.[[id]], count(cu.[[id]]) as total' ) ] )
->joinWith( ['clubUsers cu'] )
->groupBy ( 'c.id' )
->all ();
You can do this with join, in my case i get users who have more than 0 referrals.
$users = User::find()->with('referrals')
->from(User::tableName() . ' t')
->join('left join',User::tableName().' r','r.Deeplink = t.ReferralID')
->select('t.*,count(r.ID) as ct')
->groupBy('t.ID')
->andFilterHaving(['>','ct',0])
->all();
Hi your relation is correct check you error Club has no relation named \"countUsers\"."
Means you are calling a relation which not exist :
change query like this, Relation name should be in Club Model
public function getCount(){
return $this->hasMany(UserClub::className(), ['club_id'=>'id']);
}
$clubs=Club::find()->all();
foreach($clubs as $club){
echo count($club->getCount);
}
$query = Club::find()
->joinWith(['count']);
// ->with('countusers');
->all();
If you want count just do like this .
Load the Club model .
$club_model = Club::find()
$count = club_model->count;
I am trying to update my bitcoin price field in my List Token Model in my update function. This is my code I cannot seem to get it to only update the price field. Do I need to access the list elements seeing as my model is list? Is this possible to do using record syntax in elm?
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Bass exposing (style, center, h1)
import Http
import Json.Decode as Decode
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
------------- MODEL
type alias Model =
{ tokens : List Token
}
init : (Model, Cmd Msg)
init =
(initialModel , Cmd.none)
initialModel : Model
initialModel =
{ tokens = [Token "Bitcoin" "150" "11000.00"]
}
type alias Token =
{ name : String
, holdings : String
, price : String
}
------------- UPDATE
type Msg
= FetchDatabasePrice | FetchLivePrice (Result Http.Error String)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
FetchDatabasePrice ->
(model, getPrice )
FetchLivePrice (Ok newPrice) ->
( { model | price = newPrice }, Cmd.none )
FetchLivePrice (Err _) ->
(model,Cmd.none)
getPrice : Cmd Msg
getPrice =
let
url = "https://api.coinmarketcap.com/v1/ticker/bitcoin/"
request = Http.get url decodedUrl
in
Http.send FetchLivePrice request
decodedUrl : Decode.Decoder String
decodedUrl = Decode.at ["price_usd"] Decode.string
------------- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
------------- VIEW
view : Model -> Html Msg
view model =
div []
[nav
, div [] [list model.tokens]
, div [] [ button [onClick (FetchDatabasePrice) ] [text "Fetch Price"] ]
]
------BROKEN INTO PIECES---------
nav : Html Msg
nav = div [Bass.style
[center
, Bass.h1
, [("background-color", "black")
, ("color", "white")
]
]
]
[ div [] [text "Crypto Nutshell"]]
list : List Token -> Html Msg
list tokens =
div [Bass.style
[Bass.left_align
]
]
[div [ class "p1"]
[ table []
[ thead []
[ tr []
[ th [] [text "Name"]
, th [] [text "Holdings"]
, th [] [text "Price"]
, th [] [text "Actions"]
]
]
, tbody [] (List.map tokenRow tokens)
]
]
]
tokenRow : Token -> Html Msg
tokenRow token =
tr []
[ td [] [ text token.name ]
, td [] [ text token.holdings ]
, td [] [ text token.price ]
]
This is my error:
-- TYPE MISMATCH ------------------------------------------------------ test.elm
The definition of `update` does not match its type annotation.
50| update : Msg -> Model -> (Model, Cmd Msg)
51| update msg model =
52|> case msg of
53|> FetchDatabasePrice ->
54|> (model, getPrice )
55|> FetchLivePrice (Ok newPrice) ->
56|> ( { model | price = newPrice }, Cmd.none )
57|> FetchLivePrice (Err _) ->
58|> (model,Cmd.none)
The type annotation for `update` says it always returns:
( Model, Cmd Msg )
But the returned value (shown above) is a:
( { b | price : String }, Cmd Msg )
Hint: The record fields do not match up. One has tokens. The other has price.
-- TYPE MISMATCH ------------------------------------------------------ test.elm
`model` is being used in an unexpected way.
56| ( { model | price = newPrice }, Cmd.none )
^^^^^
Based on its definition, `model` has this type:
Model
But you are trying to use it as:
{ b | price : a }
Hint: The record fields do not match up. One has tokens. The other has price.
The type errors are fundamentally telling you your issue - you are trying to work on a Token, but you don't have one - you have a Model.
How do we get from one to the other? Well. We start with a model, and we can do model.tokens to get a List Token. We then want to modify that list to contain the new tokens, updated. The normal way to do this is with List.map. This operates on each Token and gives us the updated list. Following these steps:
FetchLivePrice (Ok newPrice) ->
let
updatePrice = (\token -> { token | price = newPrice })
updated = List.map updatePrice model.tokens
in
({ model | tokens = updated }, Cmd.none )
Now, the solution I've given is a simple one that will fall apart when you have multiple different tokens (they will all get changed at the same time). As you only have one right now, the same thing could be achieved just by simplifying the model to take only a single token, not a list.
You will need to start identifying which token you are getting the price for so you can update the right one, if you want to be able to use the ability to have multiple tokens.
In reality, you probably want this to end up looking something like:
FetchLivePrice tokenId (Ok newPrice) ->
({ model | tokens = tokenUpdatePrice tokenId newPrice model.tokens, Cmd.none)
Where tokenUpdatePrice is a function that manipulates your list (or other data structure - a dictionary might be appropriate, although you might need to store a separate order for presentation) to update the appropriate records. tokenId will be something used to identify the token.