I'm creating a site that has events. Each event acts as a gallery and has_many images. Each image belongs_to and event.
I followed the RailsCast #253 CarrierWave gem. When I try to add a new image, it says
undefined method `event_id' for # Image:0x7302438
<%= form_for #image, :html => {:multipart => true} do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :event_id %>
<%= f.label :title %><br />
<%= f.text_field :title %>
Here is my image.rb
class Image < ActiveRecord::Base
attr_accessible :event_id, :title, :image
validates :title, :image, :presence => :true, :uniqueness => :true
belongs_to :event
mount_uploader :image, ImageUploader
end
and the event.rb
class Event < ActiveRecord::Base
attr_accessible :title, :date, :about
validates :title, :about, :date, :presence => :true
validates :title, :uniqueness => :true
has_many :images
extend FriendlyId
friendly_id :title, use: [:slugged, :history]
end
Running this in a migration worked. Column wasn't added.
def up
change_table :images do |t|
t.references :event
end
end
Related
I am trying to create a drop-down-select menu that users can be selected from. I want to also have the number of projects they are assigned to displayed next to their name
class User < ActiveRecord::Base
attr_accessible :email, :username, :password, :password_confirmation, :remember_me, :first_name, :last_name
belongs_to :department
has_many :project_assignments
.
class ProjectAssignment < ActiveRecord::Base
attr_accessible :user_id, :project_id, :active, :notes
belongs_to :user, counter_cache: :projects_count
belongs_to :project
end
.
class Project < ActiveRecord::Base
attr_accessible :program_id, :title, :status, :topic_number, :award_number, :task_data_attributes, :user_ids, :technical_poc_id, :contacts_attributes, :project_fields_attributes, :division_id, :company_name
attr_accessor :old_project_id
belongs_to :program
belongs_to :division
belongs_to :company
has_many :users, through: :project_assignments
.
<div class="col-md-12">
<p>New Assignment</p>
<%= form_for #project.project_assignments.new, url: program_project_assignments_path(#program, #project), html: { id: 'staff-form' } do |f| %>
<%= f.select :user_id, options_from_collection_for_select(User.all, :id, :full_name), {}, class: 'form-control input-sm', placeholder: 'User' %>
<%= hidden_field_tag "project_id",nil,:value => #project.id %>
<%= f.submit 'Assign', class: 'btn-gray' %>
<% end %>
</div>
All the above code is just excerpts from their respective files. The above html works for populating the drop-down with names, but obviously no code there is attempting to add the number of assigned projects
Use options_for_select
<%= f.select :user_id, options_for_select(User.all.collect{|u|["#{u.full_name} #{u.project_assignments.count}", u.id]}), {}, class: 'form-control input-sm', placeholder: 'User' %>
It will be efficient to load the users and eager load project assignment in your controller
#users = User.includes(:project_assignment).all
Hi there,
I'm starting to use Rails through a little project. All the main things are between some Doctors, patients and consultations.
I'm learning with a book to start my application and for now, it works well but i still need help for little twists!
For example, once a doctor is created, i can create a consultation but my consultation needs a patient and i don't understand how to render a list of patients in the creation of my consultation.
Does someone have a clue?
PS: This is my code
=> DOCTOR
require 'digest'
class Doctor < ActiveRecord::Base
attr_accessible :birthdate, :birthplace, :city, :country, :firstname, :id_card_no, :lastname, :mail, :password, :secu_no, :street, :street_number, :zip
attr_accessor :password
validates :birthdate, :birthplace, :city, :country, :firstname, :lastname, :id_card_no, :secu_no, :street, :street_number, :zip, :presence=>true
validates :id_card_no,:secu_no, :uniqueness=>true
validates :street_number, :zip, :numericality=>true
validates :password, :confirmation => true,
:length => { :within => 4..20 },
:presence => true,
:if => :password_required?
validates :mail, :uniqueness => true,
:length => { :within => 5..50 },
:format => { :with => /^[^#][\w.-]+#[\w.-]+[.][a-z]{2,4}$/i }
has_and_belongs_to_many :offices
has_and_belongs_to_many :specialities
has_and_belongs_to_many :secretaries
has_many :consultations
default_scope order('doctors.lastname')
before_save :encrypt_new_password
def self.authenticate(email, password)
user = find_by_email(email)
return user if user && user.authenticated?(password)
end
def authenticated?(password)
self.hashed_password == encrypt(password)
end
protected
def encrypt_new_password
return if password.blank?
self.hashed_password = encrypt(password)
end
def password_required?
hashed_password.blank? || password.present?
end
def encrypt(string)
Digest::SHA1.hexdigest(string)
end
end
=> PATIENT
class Patient < ActiveRecord::Base
attr_accessible :birthdate, :birthplace, :city, :country, :firstname, :id_card_no, :job, :lastname, :secu_no, :street, :street_number, :zip
validates :birthdate, :birthplace, :city, :country, :firstname, :lastname, :id_card_no, :secu_no, :street, :street_number, :zip, :presence=>true
validates :id_card_no,:secu_no, :uniqueness=>true
validates :street_number, :zip, :numericality=>true
has_many :consultations
default_scope order('patients.lastname')
end
=> CONSULTATION
class Consultation < ActiveRecord::Base
attr_accessible :date, :hour
validates :date, :hour, :presence=>true
belongs_to :patient
belongs_to :doctor
has_one :patient_description
has_one :consultation_file
has_and_belongs_to_many :illnesses
has_and_belongs_to_many :symptoms
end
Thanks!
Thomas
I think you want to look into a "collection_select" on the "patient_id" column of the consultation.
I really like Formtastic for this, as it "understands" your fields and e.g. creates select boxes for associations or date pickers for dates automatically:
<%= semantic_form_for #consultation do |f| %>
<%= f.inputs do %>
<%= f.input :date %>
<%= f.input :hour %>
<%= f.input :doctor %>
<%= f.input :patient %>
<% end %>
<%= f.actions do %>
<%= f.action :submit, :as => :button %>
<%= f.action :cancel, :as => :link %>
<% end %>
<% end %>
However, this is not a pure Rails solution and needs an additional Gem. I am not sure if that is okay for your training purpose.
I have models product and product images. Product_images is a paperclip model. Product has many product_images. I am making an Active Admin form which uploads multiple images and shows these images to the Products view page.
However, when I save the product. The product table is updated, but not the product_image table. Image attaching normally, but I can't update fields of already uploaded image.
class Product < ActiveRecord::Base
attr_accessible :name, :product_images_attributes
has_many :product_images, :dependent => :destroy
accepts_nested_attributes_for :product_images, :reject_if => lambda { |t| t['product_image'].nil? }, :allow_destroy => true
end
class ProductImage < ActiveRecord::Base
attr_accessible :name, :style
attr_accessible :image
belongs_to :product
has_attached_file :image, :styles => { :small => "150x150>", :large => "320x240>" }
validates_attachment_presence :image
end
ActiveAdmin.register Product do
form :html => { :multipart => true } do |f|
f.inputs "Admin Details" do
f.input :name
end
f.inputs "Product images" do
f.has_many :product_images do |p|
p.input :style, :as => :select, :collection => Image::STYLES, :include_blank => false
p.input :image, :as => :file, :label => "Image",:hint => p.object.image.nil? ? p.template.content_tag(:span, "No Image Yet") : p.template.image_tag(p.object.image.url(:small))
p.input :_destroy, :as=>:boolean, :required => false, :label => 'Remove image'
end
end
f.buttons
end
UPDATE
In the products model I do:
after_update :check
def check
if ProductImage.find_by_product_id(self.id).changed?
raise "image"
else
raise "fail"
end
end
and it's alway raise "fail"
I got the same error using rails 4.1. Just solved this.
I noticed that warnings in my output:
Unpermitted parameters: _destroy, id
Unpermitted parameters: _destroy, id
Unpermitted parameters: _destroy, id
So I just passed them to permit_params:
permit_params assets_attributes: [:image, :image_file_name, :image_content_type, :image_file_size, :image_updated_at, :_destroy, :id]
to AA's resource page. And it worked.
I hope it will help.
If not - here is my listings.
ActiveAdmin.register Product do
permit_params :name, :description, :price, :brand_id, :category_id, assets_attributes: [:image, :image_file_name, :image_content_type, :image_file_size, :image_updated_at, :_destroy, :id]
form multipart: true do |f|
f.inputs "Детали" do
f.input :category_id, as: :select, collection: Category.all, include_blank: false
f.input :brand_id, as: :select, collection: Brand.all, include_blank: false
f.input :name
f.input :description
f.input :price
end
f.inputs 'Фотографии' do
f.has_many :assets, allow_destroy: true, heading: 'Фото', new_record: false do |fasset|
fasset.input :image, as: :file, hint: fasset.template.image_tag(fasset.object.image.url(:thumb))
end
end
f.actions
end
end
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :brand
has_many :assets, dependent: :destroy, autosave: true
accepts_nested_attributes_for :assets, allow_destroy: true,
:reject_if => lambda { |attributes| attributes[:image].blank? }
validate :name, presence: true
validate :description, presence: true
validate :price, presence: true
end
class Asset < ActiveRecord::Base
belongs_to :product
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
validates_with AttachmentPresenceValidator, :attributes => :image
end
You can configure ActiveRecord to cascade-save changes to items in a collection for a model by adding the :autosave => true option when declaring the association.
Try:
has_many :product_images, :dependent => :destroy, :autosave => true
Also, you can save the table data on association in the after_save callback like this:
class Product < ActiveRecord::Base
attr_accessible :name, :product_images_attributes
has_many :product_images, :dependent => :destroy
accepts_nested_attributes_for :product_images, :reject_if => lambda { |t| t['product_image'].nil? }, :allow_destroy => true
after_save :do_product_image_update
private
def do_product_image_update
self.product_images.save
end
end
I use Active admin and I need upload Galleries with a lot of images. How can I do it?
My code:
class Gallery < ActiveRecord::Base
belongs_to :event
has_many :images
attr_accessible :name, :publish, :images, :image, :images_attributes
accepts_nested_attributes_for :images, allow_destroy: true
validates :name, presence: true
end
class Image < ActiveRecord::Base
belongs_to :gallery
attr_accessible :url
has_attached_file :url, :styles => { :medium => "300x300>", :thumb => "100x100>" }
end
ActiveAdmin.register Gallery do
form html: { multipart: true } do |f|
f.inputs do
f.input :name
f.input :images, as: :file, input_html: { multiple: true}
end
f.buttons
end
end
And I have this error:
Image(#70319146544460) expected, got ActionDispatch::Http::UploadedFile(#70319105893880)
Try this:
ActiveAdmin.register Gallery do
form multipart: true do |f|
f.inputs do
f.input :name
f.has_many :images do |p|
p.input :url
end
end
f.actions
end
end
Okay, I managed to solve it:
Try to do the following:
ActiveAdmin.register Gallery do
form html: { multipart: true } do |f|
f.inputs do
f.input :name
file_field_tag("gallery_images_url", multiple: true, name: "gallery[gallery_images_attributes][][url]")
end
f.buttons
end
end
I got to that solution by following this blog post: http://www.tkalin.com/blog_posts/multiple-file-upload-with-rails-3-2-paperclip-html5-and-no-javascript
It's the third day I'm crushing on Active Admin.
I have #survey that has_many :questions and each question has_many :answers - they are actually variants users can choose from.
But still I cant put it to work, it just doesn't create anything deeper then 1 level:
even the form works properly, but nothing is created.
I have the following clases Course->Sections->Lessons.
I did the following:
form do |f|
f.inputs "Details" do
f.input :instructor, :as => :select
f.input :title
f.input :name
f.input :price
f.input :discount
f.input :slug
f.inputs "Sections" do
f.has_many :sections, :header=>"" do |section|
section.input :name
section.input :position
if section.object.id
section.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
section.has_many :lessons, :header=>"Lessons" do |lesson|
lesson.input :title
lesson.input :position
lesson.input :duration
lesson.input :_destroy, :as=>:boolean, :required => false, :label=>'Remove'
end
end
end
end
f.buttons
end
My models are as follow:
class Course < ActiveRecord::Base
has_many :sections, :dependent => :delete_all
accepts_nested_attributes_for :sections, :allow_destroy => true
attr_accessible :sections_attributes
....
class Section < ActiveRecord::Base
belongs_to :course
has_many :lessons, :dependent => :delete_all
attr_accessible :course_id, :name, :position
accepts_nested_attributes_for :lessons, :allow_destroy => true
attr_accessible :lessons_attributes
....
class Lesson < ActiveRecord::Base
belongs_to :section
attr_accessible :duration, :position, :section_id, :title
....
And it works great! I don't know what happens if I go more levels deeper.