How should i create an object with dinamic variable? - ruby-on-rails

I wanted to create a signature object, always the flag is being false, it should be true or false
i was reading the doc https://github.com/thoughtbot/factory_bot/blob/main/GETTING_STARTED.md#traits
let!(:signature) { FactoryBot.create(:signature, flag: true) }
let!(:signature) { FactoryBot.create(:signature, flag: false) }
this is the factory:
factory :signature do
flag {}
end

To make the default flag attribute false:
factory :signature do
flag false
end
Then you would do something like:
let!(:default_flag_signature) { FactoryBot.create(:signature) } // flag will be false
let!(:true_flag_signature) { FactoryBot.create(:signature, flag: true) } // flag will be true

Related

How to use conditions in Jenkins multibranch declarative pipeline "options" block?

I would like to configure the Office365 options to run based on the branch, since the URL of each branch is different
options { office365ConnectorWebhooks([[notifyBackToNormal: true, notifyFailure: true, notifySuccess: true, notifyUnstable: true, url: '']]) }
I'd suggest to create simple variable before pipeline {} block and set its value conditionally.
def webHookUrl
if ("${env.BRANCH_NAME}".startsWith("PR-")) {
webHookUrl = "https://your-first-url"
} else {
webHookUrl = "https://your-second-url"
}
pipeline {
agent {
label 'my_node'
}
options {
office365ConnectorWebhooks([[startNotification: true,
notifySuccess: true,
notifyAborted: true,
notifyNotBuilt: false,
notifyUnstable: true,
notifyFailure: true,
notifyBackToNormal: true,
notifyRepeatedFailure: true,
url: "$webHookUrl",
name: "Webhook Name"
]])
}
stages {.....}
Moreover, if you want to get full control it could be achieved by some wrapper class like this (in declarative style):
class WebhooksOptions {
// default values
Boolean startNotification = true
Boolean notifySuccess = true
Boolean notifyAborted = true
Boolean notifyNotBuilt = true
Boolean notifyUnstable = true
Boolean notifyFailure = true
Boolean notifyBackToNormal = true
Boolean notifyRepeatedFailure = true
String url
String name = "Some name"
WebhooksOptions(String url) {
this.url = url
}
}
def webHookOptions
if ("${env.BRANCH_NAME}".startsWith("PR-")) {
webHookOptions = new WebhooksOptions("https://your-first-url")
} else {
webHookOptions = new WebhooksOptions("https://your-second-url")
// you can customize notification rules as well
webHookOptions.startNotification = false
}
pipeline {
agent {
label 'my_node'
}
options {
office365ConnectorWebhooks([[startNotification: webHookOptions.startNotification,
notifySuccess: webHookOptions.notifySuccess,
notifyAborted: webHookOptions.notifyAborted,
notifyNotBuilt: webHookOptions.notifyNotBuilt,
notifyUnstable: webHookOptions.notifyUnstable,
notifyFailure: webHookOptions.notifyFailure,
notifyBackToNormal: webHookOptions.notifyBackToNormal,
notifyRepeatedFailure: webHookOptions.notifyRepeatedFailure,
url: webHookOptions.url,
name: webHookOptions.name
]])
}
stages {.....}

Mongoid aggregation with conditions

I'm using the mongoid 6.1.0 aggregation framework in my Rails 5 project. I need to add a $match pipeline if the value of a search field (text or select field) is not empty. Otherwise, it should be ignored and don't filter results. Something like:
#messages = Message.collection.aggregate([
{ '$match' => {'month': {'$gte' => #fr_mnth, '$lte' => #to_mnth}}},
{ '$group' => {'_id': '$mmsi'} },
{ '$lookup' => {'from': 'ships', 'localField': "_id", 'foreignField': "mmsi", as: "ship"}},
{ '$match' => {"ship.n2": params[:n2] if !params[:n2].blank? }}
]).allow_disk_use(true)
or to be more clear:
if not params[:n2].blank? { '$match' => {"ship.n2": params[:n2] }}
The problem is that if !params[:n2].blank? cannot be included in the aggregation framework. Is there any other alternative solution?
I don't know ruby, but maybe I understand your problem.
Pseudo-code
# DON'T DO SO! SEE UPDATE BELOW
if your_condition is true:
filter = { field: 'some value' }
else:
filter = { # always true condition
$or: [
{ field: { $exists: true } },
{ field: { $exists: false } }
]
}
Message.collection.aggregate([
# ...
{
"$match": filter
}
])
UPDATE:
As Aboozar Rajabi noted, if condition is true then we can just add $match stage to pipeline:
pipeline = [
# stages
];
if condition is true:
pipeline.push({
$match: {
# filter
}
});
The above pseudo-code (Kan A's answer) is translated to Ruby and Mongoid aggregation framework as its syntax might be a bit confusing and there're a few Mongoid aggregation examples online:
if not params[:field].blank?
filter = { "db_field_name": params[:field] }
else
filter = {
'$or' => [
{ "db_field_name" => { '$exists' => true } },
{ "db_field_name" => { '$exists' => false } }
]
}
end
I hope it would help the others who will see this page later. Also, this solution and the code in the question would be an example of using MongoDB aggregation framework in a Rails or Ruby project.

Accessing route parameters in Angular Dart

I have a dead-simple routing case that does not involve mapping views to routes. Instead, I want to parse the route/uri and set the value of some variable in my controller. So, for instance, if the route is #/foo I want to set one value, and if it is #/bar I want to set another value.
I don't have a simple pattern for doing this. Currently, I am doing something like this in my controller:
TodoController(this.http, this.scope, this.router) {
router.onRouteStart.listen((RouteStartEvent event) {
event.completed.then((result) {
if (result) {
if (event.uri == '/foo') {
myVar = ...
} else if (event.uri == '/bar') {
myVar = ...
} else {
// ...
}
}
});
});
}
This strikes me as a clunky approach, but I'm not coming up with anything much better. Anyone have a better idea how I can monitor the route changes in my controller?
You can do something like this:
bool isFoo = false;
bool isBar = false;
router.root
..addRoute(
name: 'foo',
path: '/foo',
enter: (_) => isFoo = true,
leave: (_) => isFoo = false)
..addRoute(
name: 'bar',
path: '/bar',
enter: (_) => isBar = true,
leave: (_) => isBar = false);
If you want to listen to route changes at a later stage, for example inside a component/controller, then you do it like this:
class MyController implements NgDetachAware {
bool isFoo = false;
bool isBar = false;
RouteHandle fooHandle;
RouteHandle barHandle;
MyController(Router router) {
fooHandle = router.root.getRouter('foo').newHandle();
fooHandle.onEnter.listen((_) => isFoo = true);
fooHandle.onLeave.listen((_) => isFoo = false);
barHandle = router.root.getRouter('bar').newHandle();
barHandle.onEnter.listen((_) => isBar = true);
barHandle.onLeave.listen((_) => isBar = false);
}
detach() {
fooHandle.discard();
barHandle.discard();
}
}
Note that in this example I'm using RouteHandle that helps us cleanup all listeners when controller is destroyed.

kendoUi grid disable column

I would like to disable column on databound based on the role security.
I am currently able to hide it not disable as the following but i have no idea how to disable it. Please advise thank you
function OnDataBound_ProductGrid() {
if ("#ViewBag.Role" == 'Admin') {
var grid = $("#Product").data("kendoGrid");
grid.hideColumn(0);
}
}
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Template(ClientTemplate("<input type='checkbox' class='checkbox'/> ");
columns.Bound(r => r.RouteName);
})
.Events(events =>ev.DataBouns("OnDataBound_ProductGrid"))
)
I agree with Antony:
Following property must be set to false:
model: {
fields: {
ProductID: {
//this field will not be editable (default value is true)
editable: false
}
}
}
And in your scenario you should be able to do following:
function OnDataBound_ProductGrid() {
if ("#ViewBag.Role" == 'Admin') {
var grid = $("#Product").data("kendoGrid");
grid.datasource.fields.ProductId.editable = false;
}
}
Wrapping/using the admin role condition around the grid definition would also do the job:
if ("#ViewBag.Role" == 'Admin') {
InnitGrid(false);
}
else
{
InnitGrid(true);
}
function InnitGrid(isEditable) {
$("#grid").kendoGrid({
dataSource: {
model: {
fields: {
ProductID: {
editable: isEditable
// or just replace isEditable with ("#ViewBag.Role" == 'Admin')
}
}
}
}
});
}
You can do this by setting the field to editable: false on the data source.
You can use a function that returns true or false, in depends what do you need.
columns.Bound(r => r.RouteName).Editable("isNotEditable");
function isNotEditable() {
return false;
}

Reloading Grails Bootstrap with environments

There is a good answer for reloading the Grails Bootstrap in Reloading bootstrap with Grails
But I have environments defined in my init closure and so I get the error:
groovy.lang.MissingMethodException: No signature of method: BootStrap.environments() is applicable for argument types: (BootStrap$_closure1_closure3) values: [BootStrap$_closure1_closure3#19ad0326]
Bootstrap code is basically the spring-security domain classes for role, user, user_role
import org.mine.*
class BootStrap
{
def init =
{ servletContext ->
environments
{
development
{
def adminRole = new DummyRole(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new DummyRole(authority: 'ROLE_USER').save(flush: true)
def user = new DummyUser(username: 'user1', email_address: 'user1#mine.org', enabled: true, password: 'password')
def user1 = new DummyUser(username: 'user2', email_address: 'user2#mine.org', enabled: true, password: 'password')
def user2 = new DummyUser(username: 'user3', email_address: 'user3#mine.org', enabled: true, password: 'password')
user.save(flush: true)
user1.save(flush: true)
user2.save(flush: true)
DummyUserDummyRole.create manager, adminRole, true
DummyUserDummyRole.create user, userRole, true
DummyUserDummyRole.create user1, userRole, true
DummyUserDummyRole.create user2, userRole, true
assert DummyUser.count() >= 9
assert DummyRole.count() >= 10
assert DummyUserDummyRole.count() >= 9
} // end-development
test {
// bootstrap data for test environment
}
production {
// bootstrap data for production environment
}
}
}
def destroy =
{
// code here
}
}
This works for me:
def servletCtx = org.codehaus.groovy.grails.web.context.ServletContextHolder.servletContext
def myBootstrapArtefact = grailsApplication.getArtefacts('Bootstrap')[-1]
BootStrap.metaClass.environments = grails.util.Environment.&executeForCurrentEnvironment
myBootstrapArtefact.referenceInstance.init(servletCtx)
Lovingly copied (and then modified) from the answer you referenced :-)
I alway used this solution and it worked for me. Works with Grails 3.x too. Here
It is much easier to just swap your syntax to:
Environment.executeForCurrentEnvironment {
production {
// do something in production
}
development {
// do something only in development
}
}

Resources