Rails 4.2 how to use Collection_select with dbms - belongs-to

Hi i have been trying to make a sample inventory system to understand rails more, but the problem is that a lot of video's is a bit messy and i cant wrap my head around how the us and make the associations + the database with the collection_select.
what i generally want to make is a an Item that has a name , description and belongs to a category, then the category has a name,
Item -> name:string description:string category_id:integer
Category -> name:string
so that i can learn more about associations i want the item that belongs to a category dynamic , i mean i can add 10 things in the category and then you can choose from the 10 categories that you added into the item.
but i can't properly wrap and make this , can someone help me code this , as i am a bit new on rails so i can't properly do this.
can you pls add how to make this, as it would really be a great learning curve as the other video's that i saw is not working when i try to do it. any help would realy be appreciated

that is pretty simple to do
in your _form.html.erb you have to do this
<%= f.select(:categories, Category.all.collect {|c| [ c.name, c.id ] }, {}, { multiple: true , class: "form-control" })%>
</div>
to whitelist all the categories params you have to change your controller
def item_params
params.require(:item).permit(:name, :description, :categoriess => [:id ])
end

Related

What pattern can I use to modify several child attributes on the same form?

I have a Rails 3.2 project where:
Product has_many Descriptions
These Descriptions have a description_type and a language_code. Different types of Products can have different types and numbers of Descriptions, so that a Product of type 'Catalogwill have 4 different Descriptions, where a product of typeWholesale` will have only 2.
Upon the creation of a Product, an after_create method creates the different descriptions for the product, filling in only the description_type. The idea is that the user then goes in and fills in the different description values.
Now I am in the situation where I have to dynamically build some complex form with a different number of descriptions, then pass all those description values via the controller to some class method on either Product or Description to persist the data, and it just ends up as spaghetti everywhere.
I am convinced that I'm thinking of the problem wrong. I can't unthink it though, as this is one box I seem to put myself in over and over.
Is there some pattern that I can apply to the problem domain of nesting these child attributes in an existing form? I have to do it on Edit, because I don't know how many fields to create until the product_type is chosen. Again, I'm open to doing this completely differently.
I always run into this problem, and it ties me in knots. I am convinced that I am approachin
Just today I had to rebuild a Member form in our app, where a Member belongs to a User which has many PhoneNumbers.
The Member model accepts_nested_attributes_for :user and the User model accepts_nested_attributes_for :phone_numbers
Using the cocoon gem, I am able to do the following in my Member form:
# phone number fields in members/_form.html.haml
# if you do use this on a new (know you said edit but just in case) ... be sure to instantiate the association
# in my case: #member.user.phone_numbers.build
# u represents the User part of the form ... typically 'f'
= u.simple_fields_for :phone_numbers do |phone|
= render 'users/phone_number_fields', f: phone
.add-phone-link-wrapper.pull-right
= link_to_add_association 'Add Phone', u, :phone_numbers, class: 'btn btn-orange btn-mini add-remove-links', partial: 'users/phone_number_fields', render_options: { wrapper: 'bootstrap' }
# 'users/phone_number_fields' partial
.nested-fields
= f.input :phone
= f.input :phone_label, as: :select, collection: PhoneNumber::LABELS
= f.input :display_number, as: :boolean
= link_to_remove_association 'Remove Phone', f, class: 'btn btn-red btn-mini add-remove-links pull-right', render_options: { wrapper: 'bootstrap' }
Note: I use SimpleForm and cocoon has some differences in implementation depending on your form builder (all on their github page/wiki).
For our needs, this fit perfectly.

Ordering records when using has_and_belongs_to_many relation in Rails 3?

I am, for the first time, trying to use a HABTM relationship in my Rails application. The following image shows the models and their relations to each other:
Currently I am displaying all members within a region with the following:
<% #region.members.each do |member| %>
<%= link_to member.name, member %>
<% end %>
I am trying to sort/order the list of members by their respective level. I then would like to have the members ordered in descending alphabetical order.
So, the members_controller code is currently the default:
#members = Member.all
I can order the results into alphabetical order:
#members = Member.order("name DESC").all
but I can't figure out how to use a related model's data to order the member records. There are likely going to be three levels; Charity, Basic and Subscription. I am planning on having a block at the top of the page which only shows subscription members. The subscription members should not then be shown again on the page.
#subscribed_members = Member.where(:level == 1).order("name DESC").all
but, as you can see, I have no idea how to filter that block by level.
Can anyone point me in the right direction, or maybe to a tutorial for this? I've read through the Rails guide for HABTM relationships but it only seems to cover the models.
EDIT
After trying the suggestion, I now have the following:
#members = Member.all
#subscribedmembers = Member.include(:levels)
.where("levels.name == 'subscriber'")
How do I use that method in the regions view?
<% #region.subscribedmembers.each do |member| %>
<%= member.name %>
<% end %>
That won't work because it's looking for a related model called subscrivedmembers which doesn't exist.
For this kind of task, i recommend you to take a look at joining models with ActiveRecord. The methods are include and joins. Lemme demonstrate with a piece of code:
#subscribed_members = Member.include(:levels)
.where("members.url == 'test_url'")
.order("levels.name DESC")
If you check your console after this query is run, you can see the include makes a SQL join with the two tables. Here i am assuming member :has_many :levels, so you include the :levels table and use a prefixed column name on your order clause.
It is not that hard once you get the idea, so i encourage you to try these two methods on the console and check the results.
EDIT
Create a scope with you query code, then use it on any place. Example:
# On your model
scope :ultimate_level, include(:levels).where("name = 'test'").order("levels.name DESC")
# On your controller
#subscribed = Member.ultimate_level
# On your view
<% #subscribed.each do |s| %>
You can create different scopes too, each one that makes a single operation, and then reuse on our controllers, etc.
Obs.: Check the syntax, i didn't test the code myself.

Rails, gem with functionality in between enum and many to many

i have im my rails app model which has few options (no more than 10 i think).
Something like Product - Category, where product can be part of 1 or many categories.
But i think i have too few categories to engage fully fledged many-to-many construct.
Moreover the list of categroies is predefined and will almost never change.
I think from sql side this could look like string field categories with such content:"Fruits|Vegetables|..."
Maybe someone know preexisting gem for such functionality, or maybe it is no real advantage doing so and i should choose standart many-to-many ?
I checked acts-as-taggable-on plugin, but it is i think fits not very well for this task.
Enum gems like enumerize i think fit just best, but they are allow only single single value to be choosen.
Currently came out with following combination:
This gem:
https://github.com/pboling/flag_shih_tzu
In model:
class Product < ActiveRecord::Base
KINDS = { 1 => :fruit, 2 => :vegetable }
include FlagShihTzu
attr_accessible *KINDS.values
as_flags KINDS
Then in view (haml):
=form_for [#product] do |f|
-Product::KINDS.each do |k, v|
=f.check_box v
=f.label v
UPDATE:
Yet another gem adressing this problem: https://github.com/joelmoss/bitmask_attributes

Web app design questions - RoR 3

This is my first web app that i am developing and i have some design questions, i have a few book about RoR3 but i dont seem to find answers to my questions.
My application is based on Ruby on rails 3
I am not looking for detailed answers here, if you can just point me to a topic name that i could learn about that can answer my qustions, such as "names resources" , "hidden fields" .....
My questions:
1- How to send information between View A and controller B. Example, i am on the View for "Company" when i click create employee i am calling the "new view" for the employee so i am now on a different view, how can i pass to the new employee action the ID of the company? Since i am now on a different view ? i don’t want to use nested resources
What are the different ways to send information across different controllers/views
2- ruby URLs: i can view am item in my model via the URL: http://localhost:3000/Companies/1
I don’t want the url to contain the index of the item, each company has a name and i want to display this name in the url such as http://localhost:3000/Companies/myCompany
How can i change the url structure of rails?
For your first question, you can pass the parameters with the link (assuming you have employee and company variables accessible to your view):
Edit: this should work:
= link_to "create employee", :controller => "employees", :action => "new", :company_id => #company.id
And in the Employees controller:
def new
company_id = params[:company_id]
# check that company_id is not nil before doing stuff with it
end
I'm not sure why doing this ignores any extra parameters:
= link_to "create employee", new_employee_path, :company_id => #company.id
For your second question, this is what you're looking for.
Pass the company id as parameters at create employee link .
In the controller ,receive the params like
def new
company_id = params[:company_id]
....
end
For using some string instead of id , use gem 'friendly_id'
Make sure your reference string should be unique.

Rails: Find by related model attribute?

So, I tried to search for an example of how to do this, and I'm not sure I even know how to describe what I'm trying to do. I'm an utter noob when it comes to SQL, and I'm sure this is really basic but I'm totally lost:
I have a model, Photo, which has_many :tags, :through => :taggings. Tags have a name and an id.
I want to do something like: Photo.where( #tag_name in [array] )
... but like I said I have no idea how to write something like that, or what to search to see an example on Google.
Can anyone give me an example of that kind of query, and what it might be called?
Thanks!
Just tried this on a similar model of my own and seemed to work fine:
Photo.joins(:tags).where('tags.name' => ['herp','derp']).group(:id)
Also, here's a great resource on the AREL querying interface rails 3 uses, with information on these and other ActiveRecord calls related to querying.
So, as a twist on Brett's method, it turns out the following works without breaking PostgreSQL:
def self.tagged_with( string )
array = string.split(',').map{ |s| s.lstrip }
select('distinct photos.*').joins(:tags).where('tags.name' => array )
end
Problem solved! See this article for a great explanation as to why this is a better idea than 'group'.