-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtutorial.html.erb
More file actions
679 lines (553 loc) · 27.2 KB
/
tutorial.html.erb
File metadata and controls
679 lines (553 loc) · 27.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
## Introduction
This tutorial is designed for learning basepack which is based on Ruby on Rails framework. So previous experience with Ruby on Rails is necessary but you do not need to be an expert. There is the [README] (https://github.com/lksv) for shorter introduction and demonstration of basepack.
Basepack is a collection of gems (which are useful in any application) tied together with additional features on top of it.
Installing basepack's gem really enhances the power of Ruby on Rails. And remember you can still use everything what development in Ruby on Rails provides. For example use basepack's features only in parts of application.
For easy start it is highly recommended that you are familiar with gems below (you have used them at least in one application) because these gems are essential part of basepack. Although there is no need to worry if you do not know them you will be supplied with additional links to related sections through all tutorial.
* [Devise](ttps://github.com/plataformatec/devise)
* [Cancan](https://github.com/ryanb/cancan.git)
* [Rails_admin](https://github.com/sferik/rails_admin) (especially [rails_admin DSL](https://github.com/sferik/rails_admin/wiki/Railsadmin-DSL))
* [InheritedResources](https://github.com/josevalim/inherited_resources)
* [SimpleForm](https://github.com/plataformatec/simple_form)
* [Nested-form](https://github.com/ryanb/nested_form)
And being familiar with these may also help:
* [Ransack](https://github.com/activerecord-hackery/ransack)
* [Kaminari](https://github.com/amatsuda/kaminari)
* [bootstrap-sass](https://github.com/thomas-mcdonald/bootstrap-sass)
The basepack requires rails 4 and ruby 2 or higher, these versions were used in this tutorial.
```console
rails -v
ruby -v
```
> Rails 4.0.0
> ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
<!--
TODO Overview - listing sections
This tutorial walks you through construction of issue tracking application because best way to learn is by creating. Check out how the [application](TODO finished application) will look like at the end.
Installation - you will learn how to install basepack to your application and basics of working with basepack.
Nested resource - what it is and how it works and how you can use it
Default query - what is it and how to set it.
Tagged issues with acts_as_taggabale
Cancan
Customize Project's show page
Namespaces
-->
## First application with basepack
In this tutorial you will create issue tracking application, let's start by creating new rails application.
```console
rails new basepack_tutorial
cd basepack_tutorial
```
Then add basepack gem to the application and run bundle to install it with all its dependancies.
> Gemfile:
```ruby
gem 'basepack'
```
```console
bundle install
```
This will create a new basepack generator for us let's use it right away.
```console
rails g basepack:install
```
The basepack generator notices the absence of cancan and devise files and offers you running generator for them as well.
Then it asks for confirmation to remove application.html.erb in order to use own application.html.haml with related partials (header, navigation, etc.). You can see how it looks in demo application.
<!-- (TODO - see the screenshots below) -->
<!-- TODO links to files on github -->
<!-- TODO point to diff commit -->
<!-- TODO seperate generators for cancan, devise and cancan -->
Here is the summary of what generator did:
* Added assets to ```application.js``` manifest file
* Created new stylesheet ```app/assets/stylesheets/basepack_and_overrides.css```
* Created new ability file ```app/models/ability.rb```
* Added permissions for Filter to ability file
* Added gems to ```Gemfile```
* Created [settings file](https://github.com/binarylogic/settingslogic) ```config/basepack-settings.yml```
* Created new models Import and Filter and database tables for them in migrations
* Created localization file ```config/locales/basepack.en.yml```
* Created new resources controller
* Replaced ```application.html.erb```
* Created partials used in basepack's template
* Added new [concern](http://guides.rubyonrails.org/routing.html#routing-concerns) to routes
* Created initializers for rails_admin and dragonfly
* Created new filters controller
Last step in installation is to define inital ability in `app/models/ability.rb`. For now you can allow anybody to perform any action and then migrate database.
> app/models/ability.rb:
```ruby
can :manage, :all
```
```console
rake db:migrate
```
Everything is set up and ready to be used. Our application will need to track projects, which will have a lot of issues (has_many). Use scaffolding to create these resources. Functionality of scaffolding has been modified by basepack.
```console
rails g scaffold Project name description:text start:date finish:date
rails g scaffold Issue name description:text status:string resolution:string project:references user:references
```
Then migrate the database and run server.
```console
rake db:migrate
rails s
```
<!-- TODO - screenshots of projects, issues (out of box) -->
In comparision with basic scaffolding it includes importing, exporting of resources, pagination through records, breadcrumb table columns are sortable. It supports searching and you can save filters (more about filters later).
<!-- TODO routes -->
After scaffolding your resources, you can customize fields used in individual actions by [Railsdmin DSL](https://github.com/sferik/rails_admin/wiki/Railsadmin-DSL).
> app/models/project.rb:
```ruby
class Project < ActiveRecord::Base
has_many :issues, inverse_of: :project
rails_admin do
list do
# only these fields(name, finish) will be displayed in this order
field :name
field :finish
end
edit do
field :name
# add rich text editor as a field type
field :description, :wysihtml5
field :start
field :finish
end
show do
field :name
field :description
field :start
field :finish
end
end
end
```
> app/models/issue.rb:
```ruby
class Issue < ActiveRecord::Base
belongs_to :project, inverse_of: :issues
end
```
<!-- TODO say about association -->
<!-- wysihtml5 -->
IMPORTANT! Make sure that you define inverse_of option on has_one, has_many and belongs_to associations. It is necessary for correct functioning of **basepack**, see [Rails documentation](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Bi-directional+associations) for explaination.
Notice that files for views are not generated (directories appp/views/projects and appp/views/issues are empty), but all RESTful(index, show, new, create, edit, update, destroy) actions are working correctly. It is because views iherit default look and you can easily override these defaults by creating appropriate files.
Another difference is controllers which inherit from ResourcesController. Full inheritance hierarchy looks this way:
```ruby
ProjectsController < ResourcesController < Basepack::BaseController < InheritedResources::Base
```
If you are not familiar with [InheritedResources](https://github.com/josevalim/inherited_resources), now is a time to take a look at [it](https://github.com/josevalim/inherited_resources).
[Basepack::BaseController](https://github.com/lksv/basepack/blob/master/app/controllers/basepack/base_controller.rb) adds to inherited resources:
* defining strong parameters
* ```options``` method
* ```taggings``` method
* ```build_resource``` method
* ...
It will be disscussed later in tutorial except defining strong parameters. You just neeed to know that you don't have to define permitted parameters anymore. It is defined by RailsAdmin DSL, more precisely by what you set as visible in edit action.
> app/models/project.rb:
```ruby
class Project < ActiveRecord::Base
...
edit do
field :name
field :description, :wysihtml5
field :start
field :finish
end
...
end
```
This implicitly sets permitted params which could be written as follows:
```ruby
def permitted_params
params.permit(:project => [:name, :description, :start, :finish])
end
```
You can override these implicit settings by creating this method in case you want it.
## Nested Resource
As you can read in [RailsGuides](http://guides.rubyonrails.org/routing.html#nested-resources) nested resource is a way how to express parent-children relationship in routes.
In our application it make sense to nest issues to projects because they are logical children of projects.
> config/routes.rb:
```ruby
resources :projects, concerns: :resourcable do
resources :issues, concerns: :resourcable
end
```
You can use [belongs_to](https://github.com/josevalim/inherited_resources#belongs-to) to reflect this relationship in controller. And it ensures that:
* nested resource is really present in parent resource
* you have permission to access not just nested resource, but parent resource as well
For example when an user enters url /projects/1/issues/2. In that case issue with id 2 must belong to project with id 1.
And it checks user permissions for project with id 1 because it could be a security vulnerability if user could read issues on project he has no permitted access.
Option [optional](https://github.com/josevalim/inherited_resources#optional-belongs-to) allows to display issues independantly of parent resource.
> app/controllers/issues_controller.rb:
```ruby
class IssuesController < ResourcesController
belongs_to :project, optional: true
end
```
There is one more thing related to nested resource. When you are creating new project you may also want to create new issues. You need to explicitly allow this with [accepts_nested_attributes_for](http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for) method.
> app/models/project.rb:
```ruby
class Project < ActiveRecord::Base
accepts_nested_attributes_for :issues
...
edit do
field :name
field :description, :wysihtml5
field :start
field :finish
field :issues # display nested resource
end
...
end
```
<!-- TODO screenshot of add issue -->
## Project show page
Suppose I want to see on project show page all issues associated with that project. To do that you can customize default show page by creating appropriate view file.
You can use @project instance variable to output project's information or better render partials which will display project as it was defined in rails_admin's show block.
> app/views/projects/show.html.erb:
```rhtml
<%= render 'header' %>
<%= render 'show' %>
```
<!-- TODO - this is importnant how to emphasise this? -->
Usually you want to display content the way it is defined in rails_admin [sections](https://github.com/sferik/rails_admin/wiki#sections) (e.g. show, list, edit, ...). There are defined helper methods for some of these sections
which will use configuration from rails_admin block.
```ruby
edit_form_for(resource_or_chain, options = {})
show_form_for(resource_or_chain)
list_form_for(query_form)
query_form_for(class_or_chain, scope, options = {})
...
```
These methods returns content of section for specific resource let's call it instnce of form. Actually it is a instance of ```Basepack::Forms``` class.
Resource chain is a sequence (array) of resources in case of nested resources. You can see this sequence in a breadcrumb and you have also access to ```association_chain``` which is an empty array in project's show page. But if projects were nested resource for users e.g. url organization/3/users/2/projects/1 than ```association_chain``` would contain third organization object and second user.
In your views, you will get the following helpers:
```ruby
resource #=> @project
collection #=> @projects (with pagination)
collection_without_pagination #=> @projects (without pagination)
resource_class #=> Project
association_chain #=> array of resources
```
As you might expect, collection, collection_without_pagination (@projects instance variable) is only available on index actions.
That means you can use ```show_form_for``` to get the same content as in show page of every issue in current project. For displaying you have to use ```form_render``` because ```render``` does not know how to render instances of basepack forms (in this case ```Basepack::Forms::Show``` object).
> app/views/projects/show.html.erb:
```rhtml
<%= render 'header' %>
<%= render 'show' %>
<h3>Issues</h3>
<% resource.issues.each do |issue| %>
<%= form_render show_form_for(issue) %>
<% end %>
```
Furthermore these helpers for retrieving content of forms have pair variant without ```_for``` at the end which already contains retrieved content in appropriate actions. For example in projects show page ```show_form``` is equivalent to show_form_for(resource).
```ruby
edit_form
show_form
list_form
query_for
...
```
<!-- TODO small change to show_form to demonstrate customization -->
<!-- This code can look little complicated so it does not matter if you do not understand we will talk more about it later.
association_chain is in this case empty array because there is nothing before projects, take a look at breadcrump (projects), but we have for example users 1 project show than association_chain would contain users and it would be neccery for proper
displaying of paths.
We want to display it in list_form which needs ```Basepack::Forms::Query``` object that's why we call query on it.
-->
## Default query
Imagine that there were many (hundred) projects especially these which already ended and every time you enter project index you see these passed projects and you have to search within them. It would be better to change default query which is currently just display all projects in order as they are in database (most of the time it is order in which they were created).
And if you are familiar with [ransack](https://github.com/activerecord-hackery/ransack) it is really simple to change this default query. You just need to call method ```default_query``` in appropriate controller, which returns a hash of parameters for search.
Basepack uses ransack under hood uses, but you have to use ```f``` as a default param key for search (instead of ```q```) and for searching use ```f[s]```.
> app/controllers/projects_controller.rb:
```
class ProjectsController < ResourcesController
default_query do
{ # display projects which haven't ended yet (end today or later)
"f[end_gteq_null]" => Date.today,
# sorted by start of project
"f[s]" => 'start asc'
}
end
end
```
In case you have not worked with ransack you can watch [railscast episode](http://railscasts.com/episodes/370-ransack) by Ryan Bates for great introduction.
## Tagged issues
In this chapter you will give user possibility to add tags to issues with [acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on) gem so first step is straightforward.
> Gemfile:
```ruby
gem "acts-as-taggable-on"
```
<!--
It does not make options request(issuescontroller#taggings) it handles all routes?
Where is partial from?
-->
Then follow post installation [instructions](https://github.com/mbleigh/acts-as-taggable-on#post-installation) and create migration by generator and migrate the database:
```console
rails g acts_as_taggable_on:migration
rake db:migrate
```
The created model is located in different namespace which means basepack will not detect it automatically and you have to include it manually in the rails_admin configuration file.
> config/initializers/rails_admin.rb:
```ruby
config.included_models = Basepack::Utils.detect_models + ['ActsAsTaggableOn::Tag']
```
Mark issues model as taggabale with ```acts_as_taggable``` which will provide new methods for working with tags as specified in [usage section](https://github.com/mbleigh/acts-as-taggable-on#usage).
Especially interesting is method ```tag_list=``` for setting tags and ```tag_list``` for retrieving tags. It is enough just to display tag_list field and you are done.
Actually almost done because associations added by ```acts_as_taggable``` to make it work are also displayed as fields (Tags, Base list) so can exclude them at beginning.
> app/models/issues.rb
```ruby
class Issue < ActiveRecord::Base
...
acts_as_taggable
rails_admin do
exclude_fields :base_tags, :tags
# display tags in show actions
show do
include_fields :tag_list
end
edit do
# tags entered in comma separated syntax
field :tag_list
end
end
end
```
To make it even better render the tag_list field with basepack's [partial](https://github.com/lksv/basepack/blob/master/app/views/forms/edit/_tag_list_with_suggestions.html.haml?source=c) which uses select2 and provides autocompletion by making ajax calls to taggings method of particular controller (IssuesController in this case)
> app/models/issues.rb
```ruby
edit do
# tags entered in comma separated syntax
field :tag_list
end
```
If you want you can enable actions (new, edit, show, ...) for ActsAsTaggableOn::Tag model just add routes for these actions.
> routes.rb
```ruby
resources :acts_as_taggable_on_tags, :filters, concerns: :resourcable
```
And create controller to properly handle all routes.
> app/controllers/acts_as_taggable_on_tags_controller.rb
```ruby
class ActsAsTaggableOnTagsController < ResourcesController
# set default model (Tag is in different namespace) see https://github.com/josevalim/inherited_resources#overwriting-defaults
defaults resource_class: ActsAsTaggableOn::Tag
end
```
## Dynamicly showed and hidden attributes
Sometimes you need to hide or display field depending on the entered value of other field in new/edit form.
When you take a look at this table you will see that it is exactly what you need right now. Because resolution can be added only to closed bugs (with resolved or verified status) as you can see in this table.
<table >
<thead>
<tr>
<td>
<h4>Status</h4>
</td>
<td>
<h4>Resolution</h4>
</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">Open bugs</td>
</tr>
<tr>
<td>
<dl>
<dd >Unconfirmed</dd>
<dd>New</dd>
<dd>Assigned</dd>
<dd>Reopened</dd>
<dd>Ready</dd>
</dl>
</td>
<td>
No resolution yet.
</td>
</tr>
<tr >
<td colspan="2">Closed bugs</td>
</tr>
<tr>
<td>
<dl>
<dd >Resolved</dd>
<dd >Verified</dd>
</dl>
</td>
<td>
<dl>
<dd >Fixed</dd>
<dd >Invalid</dd>
<dd >Wontfix</dd>
<dd >Duplicate</dd>
<dd >Worksforme</dd>
<dd>Incomplete</dd>
</dl>
</td>
</tr>
</tbody>
</table>
First of all, you need to display status and resoultion field as a select box to limit possible values. You can use enum field type and than define model method with array of values which will be displayed as select box options. Check out rails_admin's [:enum field type](https://github.com/sferik/rails_admin/wiki/Enumeration) wiki page for more.
> app/models/issues
```ruby
class Issue < ActiveRecord::Base
...
rails_admin do
# show ...
# list ...
edit do
field :name
field :description
field :project
# set type of status and resolution to enem
field :status, :enum
field :resolution, :enum
end
end
# method for retrieving potencial values for status field
def status_enum
["Unconfirmed", "New", "Assigned", "Reopened", "Ready", "Resolved", "Verified"]
end
# method for retrieving potencial values for resolution field
def resolution_enum
["Fixed", "Invalid", "Wontfix", "Worksforme", "Incomplete"]
end
end
```
As table shows resolution needs to be displayed only when status is either "Resolved" or "Verified". In all other cases resolution should be hidden. Thanks to basepack you can easily do this.
> app/models/issues.rb
```ruby
...
field :status, :enum do
html_attributes do
{
data: {
"dynamic-fields" => [
{ condition: ["Unconfirmed", "New", "Assigned", "Reopened", "Ready"], field_actions: { resolution: { visible: false }} },
{ condition: ["Resolved", "Verified"], field_actions: { resolution: { visible: true }} },
]
}
}
end
end
```
Let's explain it step by step. You can add html attributes(like class, id, etc.) in configuration of any field through ```html_attributes```. Data hash is used for custom data attributes for many purposes like marking ajax requests or date picker in Rails. Basepack uses it too. In addition to dynamicly showed / hidden attributes for [dependant select boxes](https://github.com/lksv/basepack/wiki/Getting-started#dependant-select-boxes) and some field types like wysihtml5.
```ruby
html_attributes do
{
class: "my_css_class",
data: {
# this will add data-name attribute to field
"name" => "John",
# this will add data-city attribute to field
"city" => "Brno"
}
end
```
The only missing part is "dynamic-fields" attribute which will be processed by basepack. It contains list (array) of conditions and related actions (hash) when condition is met. Condition is true when given field (in this case status) is equal to any of the values specified in condition array.
```ruby
"dynamic-fields" => [
{
# when this field has one of these values -> fieds_actions are executed
condition: ["Unconfirmed", "New", "Assigned", "Reopened", "Ready"],
# set visibility of resolution to false (= hide resolution field)
field_actions: { resolution: { visible: false } }
},
{
condition: ["Resolved", "Verified"],
field_actions: { resolution: { visible: true }}
}
]
```
## Dependant select boxes
For better demonstration of depandant select boxes let's introduce small change to application and include versions of projects.
Project can have many versions and issue will be tied to specific version of project.
<!-- TODO which results in this database schema -->
So let's generate Version scaffold and add version_id to issues. Then migrate the database.
```console
rails g scaffold Version name project:belongs_to
rails g migration addVersionIdToIssues version:belongs_to
rake db:migrate
```
Then you need to add associations in appropriate models, do not forget inverse_of.
```
class Issue < ActiveRecord::Base
belongs_to :project, inverse_of: :issues
belongs_to :version, inverse_of: :issues
..
end
class Project < ActiveRecord::Base
has_many :versions, inverse_of: :project
has_many :issues, inverse_of: :project
end
class Version < ActiveRecord::Base
belongs_to :project, inverse_of: :versions
has_many :issues, inverse_of: :version
end
```
This leads us to our problem when you are creating or updating issue you now need to enter not just project but specific version of that project which is not working properly. Suppose you've 2 projects project A and project B. Project A has versions
1.0 and 2.0. Project B has versions 1.0, 1.1 and 1.2, it allows you to enter incorrect for example version 1.1 and project A (version 1.1 doesn't belongs to project A).
What you want to do is display only versions related to currently selected project.
Actually you might be wondering how is it even possible that options for associations are displayed in selectboxes at all.
Where are they from? These values are obtained by making ajax call to options method of particular controller of association.
For example values for project association are retrieved by options method call to ```ProjectsController```. Values for version's associations by ```VersionsController#options``` call. Basicaly controllers retrieve values of related model no matter whence they are called unless you specify otherwise. That can be done either by changing ```options_source``` in model to different url or by defining ```options``` method in controller. Here is the example of this method which demonstrates default behaviour (it's going to work the same way if you do not define this method).
> app/controllers/versions_controller.rb
```ruby
def options
authorize!(action_name.to_sym, resource_class) # CanCan
versions = Version.search(params[:f]).result
options!(collection: versions)
end
```
First line needs to be there to ensure authorization. Then it retrieves all ```Version``` records that match current search params and forward these records to parent action ```options!```. If you try manually append search params to options url ```/versions/options``` for example ```/versions/options?f[name_cont]=1.``` which will display versions with name containing substring '1.'.
<!-- TODO mention format of options -->
So you already know that every time you click on select2 field it makes call to ```options``` method to display drop-down menu with options and it display all records as options unless you specify search parameters.
Yes, that's cool. But how to set these parameters in new or edit form with current values? The basepack once again make use of html attributes more precisely html data attributes.
> app/models/issues.rb
```ruby
field :version do
html_attributes do
{ data: {
# set project's field as dependent select box
"dependant-filteringselect" => "field=project_id",
# post parameters
"dependant-param" => "f[project_id_eq]"
}
}
end
end
```
To display only versions which belongs to currently selected project it marks projects field as "dependant-filteringselect".
Id of currently selected project (if there is any) is send as parameter("f[project_id_eq]") to ```VersionsController#options```.Without defining "dependant-param" id of currently selected would be send in params[:undefined] which would be ignored by ```options``` method.
You do not have to use search params and write you options method the way you want but most of the time using search params and default ```options``` method will be sufficient.
<!-- continue -->
<!-- TODO identifying field -->
It works quite well except it displays all versions as options at beginning. To deal with this unique case you can set default options query send when form (new or edit) is rendered for the first time. It can be defined in ```options_source_params``` block.
You have to remember that you are working with both new and edit form. In new form it would be enough to set default query "f[project_id_eq]" to id of non-existing project which will not display any versions at the beginning.
> app/models/issues.rb
```ruby
field :version do
options_source_params do
{ "f[project_id_eq]" => -1 }
end
html_attributes do
{ data: {
# set project's field as dependent select box
"dependant-filteringselect" => "field=project_id",
# post parameters
"dependant-param" => "f[project_id_eq]"
}
}
end
end
```
But if you want to change version in edit form of existing issue that has project already set it would display no versions as well. Unless you select a project which override default id -1. So if the issue(```bindings[:object]```) has project set use that ```project_id``` as a default query otherwise use -1.
> app/models/issues.rb
```ruby
options_source_params do
{ "f[project_id_eq]" => bindings[:object].try(:project_id) || -1 }
end
```
<!--
cancan - manage
routes
created controller
-->