Simple_form association multiple - ruby-on-rails-3

I am using a simpleform collection association input, as checkboxes in order to allow users to choose 1+ items from a list as part of an order. The list has a has_and_belongs_to_many association with the overall order. I want them to be able to do multiple of the same items, however. So I would want a small number input next to each checkbox. I can handle the javascript, I am just wondering how to do this with simpleform, if its even possible.
Thanks!

It is possible if you write a custom input for this specific task.
You would need to put it in # app/inputs/your_input.rb for Simple_form to automatically pick it up.
Then in the file :
class YourInput < SimpleForm::Inputs::Base
def input
# Your code here, but I just pasted the example that adds something after the existing field already as a reference.
"$ #{#builder.text_field(attribute_name, input_html_options)}".html_safe
end
end
and in the form :
f.input :money, as: :your
In case of checkbox, the method name will change to "check_boxes" from "input"

Related

How can I write a form to input a list of text with ActiveAdmin?

I'm writing an ActiveAdmin form for a record which takes an Array of Strings. Let's call them widgets. I'm using a multi select form like so:
ActiveAdmin.register Things do
permit_params widgets[]
form do |f|
f.inputs do
...
f.input :widgets,
as: :select,
collection: [],
multiple: true
end
end
end
With a bit of Javascript to help the user can enter their widgets and it will be delivered as an Array of Strings just fine. But when editing an existing record the existing record.widgets are not filled into the field, the widgets field is blank. I suspect what's happening is ActiveAdmin/Formtastic is interpreting this select as a has_many relationship with Widget, and the Strings as Widget IDs. ActiveAdmin is ignoring the failure.
How can I write an input to pass a plain Array of Strings into a model with ActiveAdmin? I'd like my parameters as params[:thing][:widgets] = ["foo", "bar"]
By providing collection: [], you are telling the form to always start with blank array.
You need to provide the actual Thing's widgets to the form. You'll need to modify the example to play well with the select box / javascript you wrote - just bear in mind that collection takes an array - collection: resource.widgets.split(',').

Get parent attribute within new child form?

I have a simple Rails 3 application and I am trying to create a new record that belongs to it's owner. It's working by passing the id to a hidden field in the new form of the child record.
This works well and once the new child form submitted it correctly gets associated in the child/parent relationship.
What I am trying to do, is lookup values form the parent within the new child form. The problem is that the child relationship is not yet created. Is there anyway I can use a .where lookup in the view? Or, is there a better way of doing this?
At the moment I am passing the animal_id though to the new Claim form and it's inserted into a hidden field labelled animal_id.
What I am trying to do:
<%= #animal.where(:animal_id => params[:animal_id]).id %>
The above would ideally get the animal ID from the soon-to-be-associated animal. Is there any sort of before_filter or anything that could take the passed params from the URL and temporarily create the relationship just for the new form view and then permanently create the relationship once the form is submitted?
I've tried adding the following to my Claims controller and then called #animal.AnimalName in the view but I get NoMethodError:
before_filter :find_animal
protected
def find_animal
if params[:animal_id]
Animal.find(params[:animal_id])
end
end
The URL of the new claim is correctly showing the animal ID so I'm not sure why it's not finding it:
http://localhost:3000/claims/new?animal_id=1
The model relations are as follows:
animal has_many claims
animal has_one exclusion
claim has_one animal
exclusion has_one animal
Update
I've corrected my relationships to as follows:
animal has_one exclusion
exclusions belong_to animal
First, you should also update
claim has_one animal
to be
claim belongs_to: animal
, since you already have
animal has_many claims
From this, it seems like the parent is the Animal, and the Claim is the child, thus the child claim form is trying to somehow access the parent animal's id.
If I correctly understood your situation up to this point, why not just access the animal_id value you passed to the form? You've already passed that value to the new method in the claims_controller, right?
So when you press the submit button, and it passes all the values of the form, including the animal_id value, to the create method of the claims_controller,
claims_controller.rb
def create
#claim = claim.new(claim_params)
if #claim.save
redirect_to claim_path(#claim)
else
render 'new'
end
end
private
def claim_params
params.require(:claim).permit(:foo, :bar. :animal_id)
end
Explanation:
Once you click submit in your form, it will POST all of the data in the params hash called :claim. :foo :bar :animal_id would be three hypothetical names of three of your form fields, including your hidden animal_id.
We make a private method to take the accepted input strings form the form, and do .require and .permit to prevent from sql injection.
The claim_params method returns the hash of parameters required to pass into the Claim.new method so that you can create a new Claim object (aka row, aka record).
So claim.new(claim_params) creates a new claim from the form, including the animal_id, via the claims_params method's return value, which is was filtered from the form input.
The .new method creates a record, but does not actually save into the table.
.save does.
Alternatively, instead of using .new and .save, you can use .create, which does both in succession in one shot.
Hopefully I understood your app, question, and needs well enough for this to be what you need.
I'm curious,
Also, can you clarify what is being excluded? That is, what the exclusion table looks like.
Is the purpose to simply prevent some animals from being listed and "claim-able?"
What reason would there be for your application that it couldn't have the Animals model have a column named :excluded, and validate against duplications (the point being that you don't have one row of an animal as excluded and a second row of the same animal not excluded, resulting in a duplication)
Is there any sort of before_filter or anything that could take the
passed params from the URL and temporarily create the relationship
just for the new form view and then permanently create the
relationship once the form is submitted?
I think the 'thing' you are looking for is build. Before filter will not solve that problem nicely.
Ruby on Rails. How do I use the Active Record .build method in a :belongs to relationship?
Build vs new in Rails 3
If it doesn't help can you post in here how did you implement models associations ?
with the relations update:
animal has_one exclusion
exclusion has_one animal
due to documentation for has_one (http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one)
Specifies a one-to-one association with another class. This method
should only be used if the other class contains the foreign key.
and that somehow implicates that at least one side should have belongs_to definition on or
has_many through something

using batch_action on activeadmin to batch edit records (rails with activeadmin)

I want to use batch_edit in activeadmin to edit multiple products and assign them to categories.
So, Simply I want to get all selected IDs and display other form inside active admin to assign these products IDs to category from a drop down menu.
How can I do that using ActiveAdmin and batch_actions ?
you just need to add the selectable_column to your index view
index do
selectable_column
column :company if current_admin_user.admin?
...
end
this by default will give you the batch delete action, you can add your own actions.
ActiveAdmin docs provide info about how to do it

mongoid - Dynamic date/time attribute - MultiParameter Exception

I have a model named Form, which get fields as per user requirement, eg if user puts text field in the form then a attribute is created in Form model for storing string data.
Similarly I want to store date/time and datetime values. So I added
include Mongoid::MultiParameterAttributes
in the form model, because date and time values are submitted from for in multiple attributes.
But I get Mongoid::MultiParameterAttributes::Errors::MultiparameterAssignmentErrors exception in the controller create action, on the line #form = Form.new(params[:form])
def create
#form = Form.new(params[:form])
if #form.save
redirect_to(form_path(#form))
else
redirect_to :action => "new"
end
end
How do I get through this.
Please Help
Modify your Form class so it looks like the one below.
class Form
include Mongoid::Document
include Mongoid::MultiParameterAttributes
...
end
The ruby driver can only serialize Time objects. That might be your problem.

How to user defined friendly URLs in Rails 3?

Now i have something like this
http://myapp.com/pages/1
http://myapp.com/pages/2
http://myapp.com/pages/3
http://myapp.com/pages/4
And each page belong to one user
What i need is to each user to set it's own custom name for the page.
I was thinking of using the friendly_id gem http://norman.github.com/friendly_id/
but I don't find any method to directly edit the slug to set a custom friendly url
how should i proceed?
FriendlyID is a great gem.
It shouldn't be hard to implement user defined page URL.
Create table pages with user_id and link
class User < ActiveRecord::Base
has_many :pages
class Page < ActiveRecord::Base
belongs_to :user
has_friendly_id :link # link is name of the column whose value will be replaced by slugged value
On the page#new you add an input for the link attribute.
Alternatively, you could set friendly_id on title or something else with :use_slug => true option. This way FriendlyID will take the title and modify it so it doesn't have and restricted characters. It will use it's own table to store slugs. Use cached_slug to increase performanse.
Updated
To give users a choice whether they wan't to set a custom link, you could do this:
Set friendly_id on the link field without slugs..
Make a virtual attribute permalink so you could show it in your forms.
In the before_filter, check whether the permalink is set.
If it is, write it to the link field.
If it's not, write title to the link field.
FriendlyID uses babosa gem to generate slugs. If you decide to use it as well, this is how your filter could look like:
protected
def generate_link
#you might need to use .nil? instead
self.link = self.permalink.empty? ? make_slug(self.title) : make_slug(self.permalink)
end
def make_slug(value)
value.to_slug.normalize.to_s #you could as well use ph6py's way
end
Adding to_param method to one of the models should help:
def to_param
"#{id}-#{call_to_method_that_returns_custom_name.parameterize}"
end
Hope this is what you are looking for :)
I am not using the friendly_url gem and am not sure whether my way is efficient. But it works fine for me.
I have a model called Node with id and friendly url field called url_title.
My routes.rb file:
resource 'nodes/:url_title', :to => 'Nodes#view'
nodes_controller.rb
class NodesController <ActiveController
def view
#node = Node.find_by_url_title(:params(url_title))
end
end
And use the #node variable to populate your view.
Now, whenever I type www.example.com/nodes/awesome-title , it takes me to the proper page. One argument against this can be need to create an index on a non-primary field. But I think that might be required for better performance even in the friendly_url gem. Also, the non-primary field url_title needs to be unique. Again, this might be required even for correct working for friendly_url .
Feel free to correct me if I am wrong in these assumptions.
There are a variety of ways, you can achieve this-
1) using Stringex
2) sluggable-finder
3) friendly_id
A complete step by step methodology with reasons for each to be used can be found out here. Happy reading!