Search in joint table - ruby-on-rails-3

i need some help to put a search field on my view.
I got a families table, and each family got 0-n books. I want to make a search that only families of a specific book are show.
Right now i am using ransack for some other simple searches:
Controler:
class FamiliesController < ApplicationController
def index
#search = Family.search(params[:q])
#families = #search.result
respond_to do |format|
format.html # index.html.erb
format.json { render json: #families }
end
end
model:
class Family < ActiveRecord::Base
has_many :names
has_and_belongs_to_many :books, :join_table => "books_families"
has_and_belongs_to_many :races, :join_table => "families_races"
attr_accessible :descr, :nome, :book_ids, :race_ids
validates :nome, uniqueness: true, presence: true
end
View:
<fieldset>
<legend>Filter for families</legend>
<%= search_form_for #search do |f| %>
<div class="field">
<%= f.label :nome, "Name: " %><br />
<%= f.text_field :nome_cont, :class => "search-field"%>
</div>
<div class="actions">
<%= f.submit "Search" %>
</div>
<% end %>
</fieldset>
<table>
<tr>
<th><%= sort_link(#search, :nome, "Name") %></th>
<th>Books</th>
<th>Descr</th>
</tr>
(...)
<td>
<ol type="disc">
<% family.books.each do |book| %>
<li> <%= book.nome %> </li>
<% end %>
</ol>
</td>
(...)
What should i do?

I'm not familiar with ransack, but your query should be achievable with SQL. I don't know your all of your table/field names, but something like this should work.
#families = Family.where("families.id IN(SELECT books_families.family_id FROM
books_families WHERE books_families.book_id IN(
SELECT books.id FROM books WHERE books.title LIKE(?)))",
"%" + params[:q] + "%")

Finally got the solution. its a simple 2 line thing:
<div class="field">
<%= f.label :books_id_eq, "Livro:" %><br />
<%= f.collection_select :books_id_eq, Book.order(:nome), :id, :nome, :include_blank => "Todos" %>
</div>

Related

rails : create children for given parent_id

i need your help to create parent-child relation.
i have a problem to make the create of the child working fine.
this is the model:
class Nccheklist < ActiveRecord::Base
has_many :children, class_name: "Nccheklist", foreign_key: "parent_id"
belongs_to :parent, class_name: "Nccheklist"
def has_parent?
parent.present?
end
def has_children?
children.exists?
end
end
the controller:
def create
#nccheklist = Nccheklist.new(nccheklist_params)
if #nccheklist.save
redirect_to nccheklists_url, notice: 'Nccheklist was successfully created.'
else
render :new
end
end
and the view :
<%= form_for(#nccheklist) do |f| %>
<% if #nccheklist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#nccheklist.errors.count, "error") %> prohibited this nccheklist from being saved:</h2>
<ul>
<% #nccheklist.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div>
<%= f.collection_select(:parent_id, #rootcat, :id, :name) %>
</div>
<br/><br/>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
when i submit the form, parent_id always equal null on database !
can someone help me please.
thanks.
add the following to the class definition
accepts_nested_attributes_for :children, allow_destroy: true

Devise polymorphic association nested attributes with simple form using rails 4

I am making a polymorphic association with devise and simple for but for some reason i cant get the params to work
here is my code:
User:
class User < ActiveRecord::Base
devise :database_authenticatable,
:rememberable, :trackable, :validatable
belongs_to :loginable, polymorphic: true
end
Designer:
class Designer < ActiveRecord::Base
has_one :user, as: :loginable
accepts_nested_attributes_for :user
end
Layout:
<%= simple_form_for [:admin, #designer] , :html => { :class => 'form-horizontal' } do |f| %>
<% if f.error_notification %>
<div class="alert alert-error fade in">
<a class="close" data-dismiss="alert" href="#">×</a>
<%= f.error_notification %>
<% if #designer.errors.any? %>
<ul>
<% #designer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
</div>
<% end %>
<div class="control-group">
<%= f.label :profile_name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :profile_name, :class => 'text_field' %>
</div>
</div>
<%= f.simple_fields_for users do |u| %>
<div class="control-group">
<%= u.label :email, :class => 'control-label' %>
<div class="controls">
<%= u.text_field :email, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= u.label :password, :class => 'control-label' %>
<div class="controls">
<%= u.password_field :password, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= u.label :type, :class => 'control-label' %>
<div class="controls">
<%= u.input :role, :label => false do %>
<%= u.select :role_id, Role.all.map { |r| [r.name, r.id] } %>
<% end %>
</div>
</div>
<div class="control-group">
<%= u.label :firstname, :class => 'control-label' %>
<div class="controls">
<%= u.text_field :firstname, :class => 'text_field' %>
</div>
</div>
<% end %>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
Controller:
def create
#user = User.new(designer_params)
#designer = Designer.new(designer_params)
#user.loginable = #designer
respond_to do |format|
if #user.save! && #designer.save!
format.html { redirect_to admin_designers_path, notice: 'Designer was successfully created.' }
format.json { render action: 'show', status: :created, location: admin_designer_path(#designer) }
else
format.html { render action: 'new' }
format.json { render json: [designer: #designer.errors, user: #user.errors], status: :unprocessable_entity }
end
end
end
def designer_params
params.permit(:profile_name, :user, user_attributes: [:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id])
end
My params seems to ignore the user attributes, i only see profile name for some reason.
Any ideas on how to fix this would be greatly appreciated
Thanks!
I managed to resolve my own issues. so i am posting the answer hoping to save someone else lots of time.
i ended up creating another private method for the user params
def designer_params
params.require(:designer).permit(:profile_name, user_attributes: [:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id])
end
def user_params
params[:designer][:user_attributes].permit(:email, :password, :password, :firstname, :lastname, :address, :postalcode, :city, :country, :role, :role_id)
end
and then using those to create my relationship
def create
#designer = Designer.new(designer_params)
#user = User.new(user_params)
#user.loginable = #designer
#designer.save!
end
also if you are having trouble viewing the nested form make sure to use the
build_ method
def new
#designer = Designer.new
#user = #designer.build_user
end

learning rails, trying to build blog categorization

I am working on building a blog with categorization. I am a bit stuck on how to implement categorization in the form. I have setup a has many through relationship and want to add check boxes to associate a blog with multiple categories. What I have so far is passing the categories through to the view, and I can list them out, however I cannot get the form_for method working for some reason.
Here is my code.
blog model
class Blog < ActiveRecord::Base
attr_accessible :body, :title, :image
has_many :categorizations
has_many :categories, through: :categorizations
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates :title, :body, :presence => true
end
Category Model
class Category < ActiveRecord::Base
has_many :categorizations
has_many :blogs, through: :categorizations
attr_accessible :name
end
Categorization Model
class Categorization < ActiveRecord::Base
attr_accessible :blog_id, :category_id
belongs_to :blog
belongs_to :category
end
Blog new controller
def new
#blog = Blog.new
#categories = Category.all
respond_to do |format|
format.html # new.html.erb
format.json { render json: #blog }
end
end
Blog new form view
<%= form_for(#blog, :url => blogs_path, :html => { :multipart => true }) do |f| %>
<% if #blog.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#blog.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% #blog.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.file_field :image %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="field">
Categories:
<% #categories.each do |category| %>
<% fields_for "blog[cat_attributes][]", category do |cat_form| %>
<p>
<%= cat_form.check_box :name %>
</p>
<% end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This code is my failing point
<% #categories.each do |category| %>
<% fields_for "blog[cat_attributes][]", category do |cat_form| %>
<p>
<%= cat_form.check_box :name %>
</p>
<% end %>
<% end %>
Although I am not positive I am approaching any of it right since I am currently learning. Any advice on how to accomplish this.
Thanks,
CG
First of all, you probably don't need a separate Categorization model unless there's a use case you haven't described here. You can set up a many-to-many relationship like this:
class Blog < ActiveRecord::Base
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
has_and_belongs_to_many :blogs
end
You should have a database table like this:
class CreateBlogsCategories < ActiveRecord::Migration
def change
create_table :blogs_categories, id: false do |t|
t.references :blog
t.references :category
end
end
end
Then you can construct the view like this:
<div class="field">
Categories:
<% #categories.each do |category| %>
<%= label_tag do %>
<%= check_box_tag 'blog[category_ids][]', category.id, #blog.category_ids.include?(category.id) %>
<%= category.name %>
<% end %>
<% end %>
</div>
Lastly, in your form_for, you specify url: blogs_path - you should remove this if you plan to use this form for the edit action as well, because that should generate a PUT request to /blogs/:id. Assuming you used resources :blogs in routes.rb, Rails will determine the correct path for you based on the action used to render the form.

Nested Form doesn't show assignments

I recently followed a tutorial about nested forms by Ryan Bates and did basically the same thing as he did just with other names. I wanted to nest assignments in the order form and I would like to build an assignment for every bun to that order and the user should put a count in the form.
So my controller looks like this
def new
#order = Order.new
#buns = Bun.all
#buns.each do |bun|
#order.assignments.build(:bun_id => bun.id)
end
end
And the _form partial looks like this
<%= form_for(#order) do |f| %>
<div class="field">
<%= f.label :user_id %><br />
<%= f.number_field :user_id %>
</div>
<div id="assignments" class="field">
<% f.fields_for :assignments do |builder| %>
<div id="assignment" class="field">
<%= builder.label :count, "Anzahl" %>
<%= builder.text_field :count %>
<%= builder.object.bun_id %>
<% end %>
</div>
</div>
<div class="field">
<%= f.label :due_to %><br />
<%= f.datetime_select :due_to %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The Order model has this part
has_many :assignments
has_one :user
accepts_nested_attributes_for :assignments
And the Assignments model this one:
attr_accessible :bun_id, :order_id, :count
belongs_to :bun
belongs_to :order
As i log the assignments out there are all, which should be build, so why weren't the fields rendered?
Thanks for your help!
You are missing an equal sign (=) in your erb :
<%= f.fields_for :assignments do |builder| %>

Help to render a partial from fields_for

I'm using nested_attributes and trying to implement the add/remove fields on-the-fly throu ajax following Ryan Bates screencast about Nested Model (#196)
Doing this, it won't work, but when removing the "link_to_add_fields" line, it works fine.
The problem is that I'm don't know if I doing this all associations right.
<%= form_for(#item) do |f| %>
<% if #item.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#item.errors.count, "error") %> prohibited this item from being saved:</h2>
<ul>
<% #item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :item_type_id %><br />
<%= f.select :item_type_id, #item_types.collect { |p| [ p.title, p.id ]} %>
<br />
<%= f.fields_for :item_parts do |parts_form| %>
<%= render "item_part_fields", :p => parts_form %>
<% end %>
</div>
<%= link_to_add_fields "Add Part", f, :part %>
<div class="actions">
<%= button_for "Save Item", :class => 'positive pill button', :button_type => 'submit' %>
</div>
<% end %>
Actually my models are:
"ItemPart" model:
class ItemPart < ActiveRecord::Base
belongs_to :item
belongs_to :part
end
"Item" model:
class Item < ActiveRecord::Base
belongs_to :item_type
has_many :item_parts
has_many :parts, :through => :item_parts
accepts_nested_attributes_for :item_parts, :allow_destroy => true
after_save :save_id
validates :title, :presence => true
def save_id
item_part_attributes = [ { :item_id => self.id } ]
end
end
"Part" model:
class Part < ActiveRecord::Base
has_one :part_type
has_many :item_parts
has_many :items, :through => :item_parts
end
The error I'm getting doing this way:
undefined method `klass' for nil:NilClass
Extracted source (around line #26):
23: <%= render "item_part_fields", :p => parts_form %>
24: <% end %>
25: </div>
26: <%= link_to_add_fields "Add Part", f, :item %>
27: <div class="actions">
Application trace
app/helpers/application_helper.rb:44:in `link_to_add_fields'
app/views/items/_form.html.erb:26:in `block in _app_views_items__form_html_erb__1418129287024756954_2169222480__3228169100620818569'
app/views/items/_form.html.erb:1:in `_app_views_items__form_html_erb__1418129287024756954_2169222480__3228169100620818569'
app/views/items/edit.html.erb:3:in `_app_views_items_edit_html_erb___1857878264245794505_2169270380_890290209246324491'
Application_helper.rb
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new # error line :44
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')" )
end
After hours and hours doing tests and googling a lot, I get it finally solved.
Seems that I'd to use the same local variable name to render the partial used for the form_for and then use it again as a helper method parameter needed. (In this case, "f" variable.)
I pasting the cleaning working code below
<%= form_for(#item) do |f| %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :item_type_id %><br />
<%= f.select :item_type_id, #item_types.collect { |p| [ p.title, p.id ]} %><br />
</p>
<p>
<%= f.fields_for :item_parts do |parts_form| %>
<%= render "item_part_fields", :f => parts_form %>
<% end %>
</p>
<p><%= link_to_add_fields "Add Part", f, :item_parts %></p>
<p><%= button_for "Save Item", :class => 'positive pill button', :button_type => 'submit' %></p>
<% end %>
Hope this going to help someone someday :)
There is a mistake in your add more button. This should be,
<p><%= link_to_add_fields "Add Part", f, :item_parts %></p>
The association name should be the table name on which have many relation is.