Automatic Formbuilder for Mongoid 2.0 ? Rails - ruby-on-rails

Is there a formbuilder for Mongoid 2.0 ?
Which generates automatically a form from a model.
Thanks

Why not just use Rails sacffolding?

https://github.com/mcasimir/document_form
gem document_form
It's a fork from https://github.com/justinfrench/formtastic i've made, just moved to Mongoid 2.
Model
class Person
include Mongoid::Document
include Mongoid::MultiParameterAttributes
validates_presence_of :name
field :name
field :secret, :private => true
field :birthday, :type => Date
field :department_number, :type => Integer, :range => 1..10
field :description, :long => true
end
View
<% document_form_for #object do |f| %>
<%= f.inputs %>
<%= f.buttons %>
<% end %>
This is a basic example: here the form builder will render the fields in the same order they are declared, skipping those who have :private => true.
If you are not in a hurry and you want something more flexible you can always specify fields ad options using the same syntax as formtastic, something like this:
<% f.inputs do %>
<%= f.input :title %>
<%= f.input :published, :label => "This post is published" %>
<%= f.input :section_id %>
<%= f.input :image_filename, :hint => "540x300" %>
<% end %>
If you'll decide to give it a try it i will appreciate any sort of feedback.

Related

Allow rails-bootstrap-form collection to accept enumerize values

I am trying to drop in enum values setup with the 'Enumerize' gem into the radio collection select field on a rails-bootstrap-form.
An example is shown how to do this with an ActiveRecord collection. How should I modify the example
<%= f.collection_radio_buttons :skill_level, Skill.all, :id, :name %>
So that it can accept an enum that is setup on my model
<%= f.collection_radio_buttons :level %>
skill.rb
class Skill < ActiveRecord::Base
extend Enumerize
enumerize :level, in: [:good, :ok, :bad ]
end
The Enumerize documentation says
SimpleForm
If you are using SimpleForm gem you don't need to specify input type
(:select by default) and collection:
<%= simple_form_for #user do |f| %>
<%= f.input :sex %>
<% end %>
and if you want it as radio buttons:
<%= simple_form_for #user do |f| %>
<%= f.input :sex, :as => :radio_buttons %>
<% end %>
If you're using simple-form, then the documentation says all you need to do is this:
<%= simple_form_for #skill do |f| %>
<%= f.input :level %>
<% end %>
If you're using rails-bootstrap-form, the documentation shows how to use collection_radio_buttons with Rails's built-in enum functionality, which you aren't using. So I believe you would need to pass in the Skill.level.options call as the collection values, but the :level method for (as the method, value_method, and text_method arguments):
<%= bootstrap_form_for #skill do |f| %>
<%= f.collection_radio_buttons :level, Skill.level.options, :level, :level %>
<% end %>

undefined method `[]' for nil:NilClass error in rails

I have 2 conotrollers and 3 models:
Models:
problem.rb
class Problem < ActiveRecord::Base
has_many :problemtags
has_many :tags, :through => :problemtags
end
tag.rb
class Tag < ActiveRecord::Base
validate :name, :presence => true
has_many :problemtags
has_many :problems, :through => :problemtags
end
problemtag.rb
class Problemtag < ActiveRecord::Base
belongs_to :problem
belongs_to :tag
end
problems_controller.rb
class ProblemsController < ApplicationController
def new
#all_tags = Tag.all
#new_problem = #problem.problemtags.build
end
def create
params[:tags][:id].each do |tag|
if !tag.empty?
#problem.problemtags.build(:tag_id => tag)
end
end
end
def problem_params
params.require(:problem).permit(:reporter_id, :status, :date_time, :trace_code)
end
tags_controller.rb
//tags_controller is generate with scaffold
And I have below code in problems view:
new.html.erb
<%= fields_for(#new_problem) do |f| %>
<div class="field">
<%= f.label "All Tags" %><br>
<%= collection_select(:tags, :id, #all_tags, :id, {}, {:multiple => true}) %>
</div>
<% end %>
when I run the project, the problem's view is show, but when I complete the textfields and select tags and then click on submit button, I get below error:
NoMethodError in ProblemsController#create
undefined method `[]' for nil:NilClass
Extracted source (around line #22):
#problem = #reporter.problems.build(problem_params)
params[:tags][:id].each do |tag|
if !tag.empty?
#problem.problemtags.build(:tag_id => tag)
end
I do not understand the problem. any one can describe the problem to me?
As stated by your answers, your issue is that you're not sending the right data to your controller (and consequently params[:tags] will be blank):
Form
You're firstly missing the form_builder object in your collection_select (so your tags will likely not be sent inside the correct params hash). Although this may be by design, you need to ensure you're passing the data properly:
<%= fields_for(#new_problem) do |f| %>
<div class="field">
<%= f.label "All Tags" %><br>
<%= f.collection_select(:tags, :id, #all_tags, :id, {}, {:multiple => true}) %>
</div>
<% end %>
Params
Secondly, we cannot see your form or params hash. This is vital, as your form needs to look like this:
<%= form_for #variable do |f| %>
<%= f.text_field :value_1 %>
<%= f.text_field :value_2 %>
<% end %>
This creates a params hash like this:
params { "variable" => { "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" }}}
This will be the core reason why your controller will return the [] for nil:NilClass error - you'll be referencing params which don't exist. You'll need to call params[:variable][:tags] as an example
If you post back your params hash, it will be a big help
You could try using validate :tag_id, :presence => true to check for presence of the needed params.
I found 2 problems in my code:
in new.index.html(in problem view), the submit button is in the form_for and I write the field_for outside the form_for and when I click on submit button, the params hash of tags didn't create.
In collection_select, I forgot to add the name parameter of tag.
Correct new.html.erb code:
<%= form_for #problem do |f| %>
status: <%= f.text_field :status %><br/>
datetime: <%= f.datetime_select :date_time %><br/>
trace code: <%= f.text_field :trace_code %><br/>
<%= fields_for(#new_problem) do |f| %>
<div class="field">
<%= f.label "All Tags" %><br>
<%= collection_select(:tags, :id, #all_tags, :id,:name, {}, {:multiple => true}) %>
</div>
<% end %>
<%= f.submit %>
<% end %>
Thanks for all of the answers.

many to many form, mongoid & rails 3

I have 2 models in my app. A Shopping_list and a Product
The shopping list can contain many products, a product can be a part of many shopping lists.
The shopping list -
class Shopping_list
include Mongoid::Document
field :name, :type => String
has_and_belongs_to_many :products
end
And the product
class Product
include Mongoid::Document
field :name, :type => String
has_and_belongs_to_many :shopping_lists
end
If a user visits /shopping_list/some_id/edit I want them to see -
a) The name of the product in a text box
b) A series of checkboxes listing all of the products that they can check to add to that list.
c) A submit button.
My controller looks like this
def edit
#shopping_list = Shopping_list.find(params[:id])
render :action => 'edit'
end
My view looks like this
<%= simple_form_for(#shopping_list) do |f| %>
<%= f.input :name %>
<%= f.input :articles, :as => :check_boxes %> #I know this is completely wrong. What do I do to fix?
<%= f.button :submit %>
<% end %>
This does not work at all and I'm a bit stumped. Not sure how to proceed while using Mongoid.
Advice appreciated.
try this
<%= simple_form_for(#shopping_list) do |f| %>
<%= f.input :name %>
<%= f.association :products,:collection => #shopping_list.products.collect{ |p| [p.name, p.id] }, :as => :check_boxes %>
<%= f.button :submit %>
<% end %>

Nested rails forms with Simple Form?

How can I achieve a nested rails form? Im having trouble getting this setup properly. Right now I have:
<%= simple_form_for #user do |f| %>
<%= f.input :city %>
<%= f.input :address %>
<%= f.input :zipcode %>
<%= f.association :interests, :as => :check_boxes, :label => false %>
<%= f.association :holidays, :as => :check_boxes, :label => false %>
<%= f.simple_fields_for :friend_birthdays do |friend_birthday| %>
<%= f.input :name %>
<%= f.input :gender, :collection => ['male','female'] %>
<% end %>
<%= f.button :submit %>
<% end %>
f.association is working fine for my interests & holidays models as they only need to collect a single attribute each. However, the friend_birthdays model has the same exact relationship as (interests & holidays) with the user model but requires multiple attributes to be edited/added. Any ideas?
If you are using Rails 3+, then it handles nested forms without any additional gems. The key is in using the "accepts_nested_attributes_for" method on the associations in your model, and the fields_for method on the form helper. Read up on them here and here.
I've never used simple_form, but I believe it drove the nested form development in Rails. So, taking a guess, you need to write your nested form references as:
<%= f.simple_fields_for :friend_birthdays do |friend_birthday| %>
<%= friend_birthday.input :name %>
<%= friend_birthday.input :gender, :collection => ['male','female'] %>
<% end %>
The point being, you need to call the helpers on the nested form, not the parent form.

Formtastic Confused on Has One Relationships

I'm a bit stuck on a 'has_one' and 'belongs_to' relationship and getting it to properly display in Formtastic. I have a person model that has one picture (a profile picture). I want the user to be able to select the picture using radio buttons. So far, I have:
<% form.inputs do %>
<%= form.input :picture, :as => :radio, :collection => #pictures %>
<% end %>
However, this fails (because the foreign key is stored on the 'belongs_to' side of associations in Rails. Any suggestions?
Ended up using custom controller code to fix. Use a variety of filters, etc.
Came across this in the "related" sidebar. I think this is a good use case for nested attributes -- from the Formtastic README:
Nested forms are also supported (don’t forget your models need to be setup correctly
with accepts_nested_attributes_for). You can do it in the Rails way:
<%= semantic_form_for #post do |form| %>
<%= form.inputs :title, :body, :created_at %>
<%= form.semantic_fields_for :author do |author| %>
<%= author.inputs :first_name, :last_name, :name => "Author" %>
<% end %>
<%= form.buttons %>
<% end %>
Or the Formtastic way with the :for option:
<%= semantic_form_for #post do |form| %>
<%= form.inputs :title, :body, :created_at %>
<%= form.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
<%= form.buttons %>
<% end %>

Resources