How to delete asset in nested_form through carrierwave? - ruby-on-rails

Good day.
Has somebody working solution for deleting asset in nested form in Carrierwave?
MODEL
has_many :article_images, :dependent => :destroy
accepts_nested_attributes_for :article_images
mount_uploader :image, ImageUploader
belongs_to :article, :polymorphic => true
schema.rb
create_table "article_images", :force => true do |t|
t.string "image"
t.string "article_id"
end
create_table "articles", :force => true do |t|
t.string "title"
end
CONTROLLER
def edit
#article = Article.find(params[:id])
#article.article_images.build
end
VIEW
_form.html.erb
<%= f.fields_for :article_images do |article_image| %>
<% if article_image.object.new_record? %>
<%= article_image.file_field :image %>
<% else %>
<%= image_tag(article_image.object.image.url(:thumb)) %>
<%= article_image.check_box :remove_image %> #DON'T WORK
<% end %>
<% end %>

I think it's better if you do this:
class ArticleImage < ActiveRecord::Base
# ...
attr_accessible :remove_image
after_save :clean_remove_image
def changed?
!!(super || remove_image)
end
def clean_remove_image
self.remove_image = nil
end
end
It worked for me.

What happens if you add this to your accepts_nested_attributes_for in your model:
accepts_nested_attributes_for :article_images, :allow_destroy => true
and change this in your view code:
<%= article_image.check_box :remove_image %> #DON'T WORK
To this:
<%= article_image.check_box :_destroy %> #MIGHT WORK?

Related

Nested form fields not showing in polymorphic association

Hi I have a polymorphic association with for a Document model for storing document uploads. I'm trying to submit the document attributes as a nested attribute via the associated model.
However, when I load the form, the nested field does not show. What am I missing?
Schema:
create_table "documents", force: :cascade do |t|
t.json "links"
t.integer "linkable_id"
t.string "linkable_type"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "documents", ["linkable_type", "linkable_id"], name: "index_documents_on_linkable_type_and_linkable_id", using: :btree
Models:
class Document < ActiveRecord::Base
belongs_to :linkable, polymorphic: true
belongs_to :user
belongs_to :company
mount_uploaders :links, DocUploader
end
class CustomerPlan < ActiveRecord::Base
has_many :documents, as: :linkable
accepts_nested_attributes_for :documents
end
Controller:
class CustomerPlanController < ApplicationController
def new
#customer_plan = current_company.customer_plans.build
end
def create
#customer_plan = current_company.customer_plans.build(customer_plan_params)
if #customer_plan.save
redirect_to #customer_plan, notice: 'Customer plan was successfully created.'
else
render :new
end
end
private
def cusomter_plan_params
params.require(:cusomter_plan_params).permit(:date, :name, :plan_type,
documents_attributes: [:id, links: []])
end
end
Form:
<%= simple_nested_form_for #stock_plan, :html => { :multipart => true } do |f| %>
<%= f.error_notification %>
<%= f.input :date %>
<%= f.input :name %>
<%= f.input :plan_type %>
<%= f.simple_fields_for :documents do |d| %>
<p><b>Upload here:</b></p>
<%= d.file_field :links, multiple: true %>
<br>
<% end %>
<%= f.button :submit%>
<% end %>

Act as taggable Tags are not displayed on my view

I'm using activeadmin and act as taggable gem. When I insert tags on activeadmin it saves the tags but is not displaying the tags in the view
activeadmin model:
ActiveAdmin.register Project do
index do
column :id
column :name
column :created_at
column :tag_list
default_actions
end
form(:html => { :multipart => true }) do |f|
f.inputs do
f.input :name
f.input :tag_list, :label => "Tags", :hint => 'Comma separated'
f.input :content, :input_html => {:class => "ckeditor"}
f.input :image, :as => :file
end
f.buttons
end
end
model:
class Project < ActiveRecord::Base
attr_accessible :content, :name, :image, :tag_list
mount_uploader :image, ImageUploader
acts_as_taggable
def previous_project
self.class.first(:conditions => ["name < ?", name], :order => "name desc")
end
def next_project
self.class.first(:conditions => ["name > ?", name], :order => "name asc")
end
end
View:
<% #projects.each do |project| %>
<figure class="d1-d3">
<%= image_tag project.image_url(:thumb) if project.image? %>
<figcaption>
<h4><%= link_to project.name, project %></h4>
<% project.tag_list %>
</figcaption>
</figure>
<% end %>
I tried to use <%= project.tags %> and it didn't work either
Thanks
Try to add this into your Project model (below acts_as_taggable)
acts_as_taggable_on :tags
And remember to run the migrations, example:
create_table :tags do |t|
t.string :name
end
create_table :taggings do |t|
t.references :tag
# You should make sure that the column created is
# long enough to store the required class names.
t.references :taggable, :polymorphic => true
t.references :tagger, :polymorphic => true
# limit is created to prevent mysql error o index lenght for myisam table type.
# http://bit.ly/vgW2Ql
t.string :context, :limit => 128
t.datetime :created_at
end
add_index :taggings, :tag_id
add_index :taggings, [:taggable_id, :taggable_type, :context]
What about:
row :tags do
resource.tag_list.join(", ")
end
In the view missed the equal sign
View:
<% #projects.each do |project| %>
<figure class="d1-d3">
<%= image_tag project.image_url(:thumb) if project.image? %>
<figcaption>
<h4><%= link_to project.name, project %></h4>
<%= project.tag_list %>
</figcaption>
</figure>
<% end %>

How do I add a data association between records in a HABTM many to many relationship?

I have set up a HABTM relationship between two table creating a many to many relationship between items and categories. I want to add an item connected with one or more categories via the add item form. when I submit the form I am getting the error "Can't mass-assign protected attributes: categories".
Here are my models:
class Item < ActiveRecord::Base
attr_accessible :description, :image, :name
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
belongs_to :user
has_and_belongs_to_many :categories
validates :name, presence: true, length: {maximum: 50}
accepts_nested_attributes_for :categories
end
class Category < ActiveRecord::Base
attr_accessible :description, :name
has_and_belongs_to_many :items
validates :name, presence: true, length: {maximum: 50}
end
And my migrations:
class CreateItems < ActiveRecord::Migration
def change
create_table :items do |t|
t.string :name
t.text :description
t.has_attached_file :image
t.timestamps
end
end
end
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name
t.string :description
t.timestamps
end
end
end
class CreateCategoriesItems < ActiveRecord::Migration
def up
create_table :categories_items, :id => false do |t|
t.integer :category_id
t.integer :item_id
end
end
def down
drop_table :categories_items
end
end
And my form looks like this:
<%= form_for(#item, :html => { :multipart => true }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.file_field :image %>
<%= f.collection_select(:categories, #categories,:id,:name)%>
<%= f.submit "Add Item", :class => "btn btn-large btn-primary" %>
<% end %>
and here's my Items Controller:
class ItemsController < ApplicationController
def new
#item = Item.new
#categories = Category.all
end
def create
#item = Item.new(params[:item])
if #item.save
#sign_in #user
flash[:success] = "You've created an item!"
redirect_to root_path
else
render 'new'
end
end
def show
end
def index
#items = Item.paginate(page: params[:page], per_page: 3)
end
end
Thanks for all of your help :)
-Rebekah
Mass Assignment usually means passing attributes into the call that creates an object as part of an attributes hash.
Try this:
#item = Item.new(name: 'item1', description: 'description1')
#item.save
#category = Category.find_by_name('category1')
#item.categories << #category
Also see:
http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html
I hope this helps.
IAmNaN posted the comment above that was the missing link in my code working properly. I have since written a blog post that details the process of getting the HABTM set-up. Thanks IAmNaN!

Displaying an image associated with an artist

I am trying to display an image that is in my public/image folder and I
don't know how to.
What I want to do is to be able to assign a photo to an artist so you
can navigate through different artist's photo.
This is my image model
class Image < ActiveRecord::Base
has_many :publishings
has_many :artists, :through => :publishings
has_many :comments,:through => :friends
has_many :comments, :as => :resource, :class_name => "Commentable"
end
This is my image show.html
<p id="notice"><%= notice %></p>
<p>
<b>Title:</b>
<%= #image.title %>
</p>
<p>
<b>Filename:</b>
<%= #image.filename %>
</p>
<p>
<b>Likes:</b>
<%= #image.likes %>
</p>
<%= link_to 'Edit', edit_image_path(#image) %> |
<%= link_to 'Back', images_path %>
This is the database for the images
class CreateImages < ActiveRecord::Migration
def self.up
create_table :images do |t|
t.string :title :null => false
t.string :filename :null =>false
t.integer :likes :default =>0
t.timestamps
end
end
def self.down
drop_table :images
end
end
Thanks in advance
<%= image_tag #image.filename %>

collection_select selected value

i have two identical collection_selects on one page (one message belonging to 2 groups)
<%=
collection_select(:message,:group_ids, Group.find(:all),:id, :title, {}, {:name=>'message[group_ids][]'} )
%>
<%=
collection_select(:message,:group_ids, Group.find(:all),:id, :title, {}, {:name=>'message[group_ids][]'} )
%>
is it possible to set two different selected values for them using collection_select?
edit:
i guess i'd have to do something like
<%
#message.group_id=5
%>
<%=
collection_select(:message,:group_id, Group.find(:all),:id, :title, {}, {:name=>'message[group_ids][]'} )
%>
<%
#message.group_id=6
%>
<%=
collection_select(:message,:group_id, Group.find(:all),:id, :title, {}, {:name=>'message[group_ids][]'} )
%>
but of course it doesn't work and gives method missing error
edit2:
guess there is no way to do it with collection_select. unless group has a method, returning single group_id each time.
what i ended up with is
select_tag 'message[group_ids][]', "<option></option>"+options_from_collection_for_select(Group.find(:all), 'id', 'title',group1.id)
select_tag 'message[group_ids][]', "<option></option>"+options_from_collection_for_select(Group.find(:all), 'id', 'title',group2.id)
You need to set up your models and relationships like so:
class Message < ActiveRecord::Base
has_many :message_groups
has_many :groups, :through => :message_groups
accepts_nested_attributes_for :message_groups #Note this here!
end
class Group < ActiveRecord::Base
has_many :message_groups
has_many :messages, :through => :message_groups
end
class MessageGroup < ActiveRecord::Base
belongs_to :group
belongs_to :message
end
Then in your form...
<% form_for(#message) do |f| %>
<%= f.error_messages %>
<% f.fields_for :message_groups do |g| %>
<p>
<%= g.label :group_id, "Group" %>
<%= g.select :group_id, Group.find(:all).collect {|g| [ g.title, g.id ] } %>
</p>
<% end %>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
And here's my migrations for completeness
class CreateGroups < ActiveRecord::Migration
def self.up
create_table :groups do |t|
t.string :title
t.timestamps
end
end
def self.down
drop_table :groups
end
end
class CreateMessages < ActiveRecord::Migration
def self.up
create_table :messages do |t|
t.text :body
t.timestamps
end
end
def self.down
drop_table :messages
end
end
class CreateMessageGroups < ActiveRecord::Migration
def self.up
create_table :message_groups do |t|
t.integer :message_id
t.integer :group_id
t.timestamps
end
end
def self.down
drop_table :message_groups
end
end
Hope this helps...!

Resources