Active Admin with join table relation - mysql

I am configuring Active Admin. Everything is running apart from a join table, which connects the magazine resource with the keyword resource. One magazine is defined by multiple keywords and a keyword can define multiple magazines.
I have two models:
### models/magazine.rb
class Magazine < ActiveRecord::Base
attr_accessible :colour, :cover_alt, :description, :number, :short, :title_id
has_and_belongs_to_many :keywords, :join_table => "magazines_keywords"
belongs_to :title, :class_name => "Keyword", :foreign_key => "title_id"
end
### models/keywords.rb
class Keyword < ActiveRecord::Base
attr_accessible :word, :description
has_and_belongs_to_many :magazines, :join_table => "magazines_keywords"
end
And a join table:
### models/magazines_keyword.rb
class MagazinesKeyword < ActiveRecord::Base
attr_accessible :magazine_id, :keyword_id
belongs_to :magazine
belongs_to :keyword
end
This setting works for the views of my rails app, and I have the index and show section of my AA magazine resource working, but the form (for new and edit) does not work:
ActiveAdmin.register Magazine do
menu :priority => 1
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "Magazine Details" do
f.input :title_id, :label => 'Title', :as => :select, :collection => Keyword.all.map{ |u| ["#{u.word.capitalize}", u.id] }
f.inputs :magazines_keywords do
f.has_many : magazines_keywords do |s|
s.input :keyword, :as => :select, :multiple => true, :collection => MagazinesKeyword.all.map { |u| ["#{u.keyword.word.capitalize}", u.id] }
end
end
end
f.actions
end
show do
panel "Magazine Details" do
attributes_table_for magazine do
row "Keywords", :keyword do |m|
m.keywords.map { |d| d.word }.join(", ").html_safe
end
end
end
active_admin_comments
end
end
When running the app i get NoMethodError in Admin/magazines#edit
Where /active_admin/resource/edit.html.arb line #1 raises undefined method 'klass' for nil:NilClass
I can display all the keywords in the form section with:
f.input :magazines_keywords, :as => :check_boxes, :multiple => true, :collection => MagazinesKeyword.all.map{ |u| ["#{u.keyword.word.capitalize}", u.id] }
But when I try to write them it does not work. Editing the values does not work either.
Where am I missing something? How can I get this working?
****UPDATE****
After some work I got the following solution:
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "Saft Details" do
f.input :title_id, :label => 'Title', :as => :select, :collection => Keyword.all.map{ |u| ["#{u.word.capitalize}", u.id] }
f.input :keywords, :as => :check_boxes, :input_html => {:multiple => true}
end
f.actions
end
And as suggested:
f.input :keywords, :as => :check_boxes, :input_html => {:multiple => true} do
f.has_many :keywords do |s|
s.input :keyword, :collection => Keyword.all.map { |kw| ["#{kw.word.capitalize}", kw.id] }
end
end
With both solutions I am able to write a new Magazine entry and get the association written to the join table, unfortunately it displays #<Keyword:0x10c858858> in the form and not the word. What am I missing?

ActiveAdmin is quite smart to understand what you are trying to do. So you should ignore MagazinesKeyword and go straight to Keyword model.
So you should change this:
f.has_many :magazines_keywords do |s|
s.input :keyword, :as => :select, :multiple => true, :collection => MagazinesKeyword.all.map { |u| ["#{u.keyword.word.capitalize}", u.id] }
end
with this:
f.has_many :keywords do |s|
s.input :keyword, :as => :select, :multiple => true, :collection => Keyword.all.map { |kw| ["#{kw.word.capitalize}", kw.id] }
end
Active admin will handle MagazinesKeyword by himself.

Related

how to set value in text_field and store these value into database table in rails

These things i have all ready done, but at that time the value of text_field is not insert into database table, reaming value insert successfully but one value is not inserted.
I can understand where am i wrong and what is missing...
_employee_details.html.erb
<%= form_for(:employee_details, :url => {:controller => 'hr', :action => 'create'}) do |f| %>
<%= f.text_field :employee_id, { :value=> "123548", :disabled=>true , :required => true, placeholder: 'E12345678', class: 'form-control' } %>
<% end %>
hr_controller.rb
class HrController < ApplicationController
def new
#employees = EmployeeDetail.new
end
def create
#employees = EmployeeDetail.new(employee_params)
if #employees.save
redirect_to :action => 'internal_employee_page'
else
redirect_to :action => 'internal_employee_page'
end
end
private
def employee_params
params.require(:employee_details).permit(:offer_letter_id, :employee_id, :bank_ac, :bank_ifsc, :spouse_name, :gender, :work_end_date)
end
end
All value is successfully insert into employee_details table accept employee_id
employee_details.rb this is my modal
class EmployeeDetail < ActiveRecord::Base
belongs_to :user
validates :offer_letter_id, presence: true
end
I have already try this but this is not working
Disabled input will not submit data.
Instead of disabled Use the readonly attribute:
<%= f.text_field :employee_id, { :value=> "123548", :readonly => true , :required => true, placeholder: 'E12345678', class: 'form-control' } %>
<%= form_for(:employee_details, :url => {:controller => 'hr', :action => 'create'}) do |f| %>
<%= f.text_field :employee_id, { :value=> "123548", :readonly => true , :required => true, placeholder: 'E12345678', class: 'form-control' } %>
<% end %>
Here is the documentation of it

RoR - Adding form over a static page

Can someone tell me how do I add a simple form in my rails app? I created a form on a separate page and it works fine, but how do I implement it on my static page?
My app/views/contact/_form.html.haml
.container
%h1 Contact
= simple_form_for #contact, :html => {:class => 'form-horizontal' } do |f|
= f.input :name, :required => true
= f.input :email, :required => true
= f.input :message, :as => :text, :required => false, :input_html => {:rows => 10}
.hidden
= f.input :nickname, :hint => 'Leave this field blank!'
.form-actions
= f.button :submit, 'Send message', :class=> "btn btn-primary"
My contacts controller:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
flash.now[:error] = nil
else
flash.now[:error] = 'Cannot send message.'
render :new
end
end
end
Where I want to add the form, (index.html.haml)(static page)
#callouts2
.callout_inner
.wrapper
.callout
=render 'contacts/form'
My routes.rb
Rails.application.routes.draw do
devise_for :users
resources :posts do
member do
get "like", to: "posts#upvote"
get "dislike", to: "posts#downvote"
end
resources :comments
end
authenticated :user do
root 'posts#index', as: "authenticated_root"
end
resources "contacts", only: [:new, :create]
root 'pages#index'
I also have another 'Thank you for your message' page in views/contact/create.html.haml, I need to redirect them to that page as well.
EDIT: I added a =render 'contacts/form' inside my index page but it gives me an error:
ArgumentError in Pages#index Showing
C:/Sites/blogger/app/views/contacts/_form.html.haml where line #3 raised:
First argument in form cannot contain nil or be empty Trace of
template inclusion: app/views/pages/index.html.haml
If your form is called "_form", You could do something like:
render "form"
I'm not familiar with haml, not sure what other syntax is required, but that is how you add a form into a page.

How populate select box in edit page using rails?

I have this in my form:
<%= f.select :status, options_for_select(Article::STATUS), :include_blank => true, :selected => #article.status, :class => 'select_field' %>
Model:
class Article < ActiveRecord::Base
attr_accessible :author, :content, :publication_date, :status, :title, :tag_tokens
attr_reader :tag_tokens
STATUS = ['Rascunho', 'Em Revisão', 'Publicado']
end
Why does not populate the field?
I believe you can simply pass an array in [#select][1]. You don't need to call options for collection. I also think you can ommit the :selected option if this is a model form, Rails will figure it out using the attribute value.
Try this:
<%= f.select :status, Article::STATUS, :include_blank => true, :class => 'select_field' %>

Rails content_tag inserts extra "<" and ">" characters

When doing this:
def user_log
if logged_in? == false
form_tag session_path, :id => "mform" do
content_tag(:span, content_tag(text_field_tag :email, "email#domain.com"), :class => "memail")+
content_tag(:span, content_tag(password_field_tag :password, "12345678912"), :class => "mpass")+
content_tag(:span, content_tag(submit_tag 'Login'), :class => "mbutton")
end
else
...
end
end
end
I get this:
stack overflow doesn't let me post pictures
Since I don't want the extra "<" and ">", what am I doing wrong?
EDIT: As extra information, on my view I am just doing:
<%= user_log %>
The fundamental problem is that you are using content_tag twice when you don't need to. content_tag essentially calls content_tag_string. Here's content_tag_string's source:
def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
"<#{name}#{tag_options}>#{content}</#{name}>".html_safe
end
Calling content_tag(text_field_tag :email, "email#domain.com") looks like:
"<#{text_field_tag :email, "email#domain.com"}>"
and text_field_tag already produces a full HTML tag (it includes the "<" and ">").
All you need to do to get rid of the extra angled brackets is to leave out the second content_tag:
content_tag(:span, text_field_tag(:email, "email#domain.com"), :class => "memail")+
Though I haven't tried it locally, the problem is likely that Rails is html escaping your handy helper method. To see if I'm right, try throwing this in your view:
<%= raw(user_log) %>
If that works, you can throw raw in your helper method instead:
def user_log
if logged_in? == false
raw(form_tag session_path, :id => "mform" do
content_tag(:span, content_tag(text_field_tag :email, "email#domain.com"), :class => "memail")+
content_tag(:span, content_tag(password_field_tag :password, "12345678912"), :class => "mpass")+
content_tag(:span, content_tag(submit_tag 'Login'), :class => "mbutton")
end)
else
...
end
end
raw tells Rails that this code is safe and doesn't need to be html escaped.
As a first guess, I might try something like:
if logged_in? == false
...
else
...
end.html_safe
Update: Ok, back to the drawing board.
As a second guess, try this. (And note the extra parameter to content_tag, which required putting the hash in explicit { }...)
def user_log
if logged_in? == false
form_tag session_path, :id => "mform" do
(
content_tag(:span, content_tag(text_field_tag :email, "email#domain.com"), {:class => "memail"}, false)+
content_tag(:span, content_tag(password_field_tag :password, "12345678912"), {:class => "mpass"}, false)+
content_tag(:span, content_tag(submit_tag 'Login'), {:class => "mbutton"}, false)
).html_safe
end
else
...
end
end
end

How does the HTML5 multiple file upload field map to a nested model in Rails 3?

I'm trying to use the HTML5 multiple attribute on a file field in a nested form.
The models are as follows:
class Album < ActiveRecord::Base
has_many :album_images
has_many :images, :through => :album_images
accepts_nested_attributes_for :images
end
class Image < ActiveRecord::Base
has_many :album_images
has_many :albums, :through => :album_images
mount_uploader :filename, ImageUploader
validates_presence_of :filename
end
The view:
<%= semantic_form_for #album, :url => upload_path do |f| %>
<%= f.inputs do %>
<%= f.input :name, :label => 'Album title' %>
<% end %>
<%= f.input :images, :as => :file, :input_html => {:multiple => true} %>
<%= f.buttons do %>
<%= f.commit_button 'Upload' %>
<% end %>
<% end %>
When I use for the file field:
<%= f.input :images, :as => :file, :input_html => {:multiple => true} %>
I get:
<input id="album_images" multiple="multiple" name="album[images][]" type="file">
Which doesn't doesn't seem right since I think I want to set the filename on the object directly, but I'm not sure about this. When I try to upload with this field, the incoming params look like:
"album"=>{"name"=>"2011-01-09", "images"=>["IMG_0052.JPG", "IMG_0053.JPG", "IMG_0054.JPG", "IMG_0055.JPG"]}
However, I get the following error:
ActiveRecord::AssociationTypeMismatch (Image(#2157004660) expected, got String(#2151988680)):
OK, that error is probably due to the fact that it just received a filename and not an image object. So instead, I use for the file field:
<%= f.input :images, :as => :file, :input_html => {:multiple => true, :name => 'album[images][][filename]'} %>
for which Formtastic generates:
<input id="album_images" multiple="multiple" name="album[images][][filename]" type="file">
The incoming params look like:
"album"=>{"name"=>"2011-01-09", "images"=>[{"filename"=>"IMG_0052.JPG"}, {"filename"=>"IMG_0053.JPG"}, {"filename"=>"IMG_0055.JPG"}]}
But then I get this error:
Image(#2153868680) expected, got ActiveSupport::HashWithIndifferentAccess(#2158892780)
So how does one go about setting up this multiple file input filed mapping in Rails?
Thanks.
You need to include :html => { :multipart => true } in your form_for (or in your case semantic_form_for) call so that your <form> tag is set to support file uploads.
Then revert back to your original syntax for f.input and you should be right then.