I using rails 4.0.3 and am trying to set up many to many checkboxes in Active-Admin. The checkbox selections are not being saved. This is what i have
class Product < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
accepts_nested_attributes_for :categorizations
end
class Category < ActiveRecord::Base
has_many :categorizations
has_many :products, :through => :categorizations
accepts_nested_attributes_for :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :category
belongs_to :product
end
ActiveAdmin.register Product do
permit_params :title, :price, category_ids:[:id]
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "Product" do
f.input :title
f.input :price
f.input :categories, :as => :check_boxes
end
f.actions
end
end
I have also tried using has_and_belongs_to_many but still cant not get the selections to save.
Any guidance would be highly appreciated.
Cheers
I found that adding the following to your active_admin file, product.rb, fixes it.
ActiveAdmin.register Product do
permit_params category_ids: []
end
try add
permit_params :title, :price, category_ids:[:id],
categories_attributes: [:id, :your_fields, :_update,:_create]
Related
I'm just learning cakePHP. I have a CATEGORIES table and a POSTS table. A post have one category. So there is a category_id foreign key in POSTS table.
In my Model, I have Category.php with this code.
<?php
App::uses('AppModel', 'Model');
class Category extends AppModel {
// A hasMany association will allow us to fetch a category’s posts when we fetch a Category record.
public $primaryKey = 'category_id';
public $hasOne = 'Post';
}
?>
In my Post.php I have something like this.
class Post extends AppModel {
public $hasMany = array('Photo');
public $primaryKey = 'post_id';
public $belongsTo = array('User'); // 'Category',
public $relatedImages;
public $belongsTo = 'Category';
Now in my PostController.php I have
$allCategories = $this->Category->find('list');
$this->set('allCategories', $allCategories);
The objective is to retrieve all the category from the categories table and show it in my form.
However I encountered the error of Call to a member function find() on a non-object
I'm not sure what is happening here. How can I retrieve this?
many thanks!
Use
$this->Post->Category->find('list');
As you have to goto Category table Thru posts as u r in posts controller Now currently.
In your post model try to declare the Category as below
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id'
)
);
I've tried making my has and belongs to many relation to work, following the Rails guides and everything I could find online, but they just wont show up.. When I save my form its only INSERTS into the Pin model, it doesn't insert any relations. If I add the relation manually via terminal like so:
p = Pin.new
p.minors = [1,2]
p.save
It works, but my form which looks like this (iam using rails 4, so collections yay) it doesn't save the relations (it saves the pin just fine)
new.html.erb
<%= collection_check_boxes(:minor_ids, :minor_ids, Minor.all, :id, :name) %>
<%= collection_check_boxes(:competence_ids, :competence_ids, Competence.all, :id, :name) %>
pinscontroller.rb
class PinsController < ApplicationController
def create
#pin = Pin.new(pin_params)
#pin.user_id = current_user.id
if #pin.save
redirect_to pin_path(#pin)
end
end
def new
#pin = Pin.new()
end
def show
#pin = Pin.find(params[:id])
end
private
def pin_params
params.require(:pin).permit(:title, :name, :url, { :minor_ids => [] }, { :competence_ids => [] },)
end
end
and my model Pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :minors
has_and_belongs_to_many :competences
end
Minor.rb
class Minor < ActiveRecord::Base
has_and_belongs_to_many :pins
end
Competence.rb
class Competence < ActiveRecord::Base
has_and_belongs_to_many :pins
end
pin/show.html.erb
This is the way I try to check if the relations came through. They all come back empty and 0, except for the ones I did through console.
<%= #pin.minors.count.inspect %>
<%= #pin.competences.count.inspect %>
<% if !#pin.minors.empty? %>
<%= #pin.minors.each do |minor| %>
<%= minor.name %>
<% end %>
<% end %>
<% if !#pin.competences.empty? %>
<%= #pin.competences.each do |comp| %>
<%= comp.name %>
<% end %>
<% end %>
Schema.rb
create_table "competences", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "pin_id"
end
create_table "competences_pins", force: true do |t|
t.integer "pin_id"
t.integer "competence_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "minors", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "pin_id"
end
create_table "minors_pins", force: true do |t|
t.integer "pin_id"
t.integer "minor_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "pins", force: true do |t|
t.string "title"
t.string "url"
t.string "image"
t.string "username"
t.integer "views"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
So, am I missing a step? So far i've tried everything but the minors_pins and the competences_pins tables remain empty, all the help and insight I can get!
I fixed this by adding #minors = Minor.all in the pins controller in the new method. And by replacing <%= collection_check_boxes(:minor_ids, :minor_ids, Minor.all, :id, :name) %> with <%= f.collection_check_boxes(:minor_ids, #minors, :id,:name)%>
I've been searching for hours trying to find a up-to-date example of a mutual has_many :through between 2 models that actually worked, so I finally decided I'd just ask.
My database:
schema.rb
#...
create_table "groups", force: true do |t|
t.string "group_name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "memberships", force: true do |t|
t.integer "student_id"
t.integer "group_id"
end
create_table "students", force: true do |t|
t.string "user_name"
t.string "first_name"
t.string "last_name"
t.string "password_digest"
t.datetime "created_at"
t.datetime "updated_at"
end
#...
My models:
student.rb
class Student < ActiveRecord::Base
has_secure_password
validates :password, length: { in: 6..20 }
validates :user_name, format: {with:/\w{2,7}\.\d{1,4}/}, on: :create
validates_uniqueness_of :user_name, on: :create
validates_presence_of :first_name, on: :create
validates_presence_of :last_name, on: :create
has_many :memberships, :dependent => :destroy
has_many :groups, through: :memberships
has_many :ratings, :dependent => :destroy
end
group.rb
class Group < ActiveRecord::Base
has_many :memberships, :dependent => :destroy
has_many :students, through: :memberships
validates_uniqueness_of :group_name
end
membership.rb
class Membership < ActiveRecord::Base
belongs_to :students
belongs_to :groups
end
If my authorization correctly puts the logged-in student's :user_name into session[:user_name] if I wanted to get all of the groups to which that student belonged, what would be the proper line(s)? I'm also interested in finding the students within a given group.
I tried:
#current_student = Student.find_by_user_name(session[:user_name])
#current_groups = #current_student.groups
But I was given:
uninitialized constant Student::Groups
What did I do wrong?
Change membership.rb to :
class Membership < ActiveRecord::Base
belongs_to :student
belongs_to :group
end
I have set up a hasMany through association between two tables - Books and Authors. The associations work properly, except when attempting to retrieve all the authors that belongs to a book. If I do this
$book = $this->Book->findById($id)
The array returned will not have an array Authors; it will have the AuthorToBook join model information, but it won't automatically fetch the Author associated with it.
I have to set recursive to 2 in order to retrieve the join model, and the associated Author. I am also re-fetching the Book data for each AuthorToBook association there is.
'AuthorToBook' => array(
(int) 0 => array(
'id' => '1',
'author_id' => '1',
'book_id' => '2',
'Author' => array(
'id' => '1',
'name' => 'J.R.R Tolkien',
'date_of_birth' => '1892-01-03 00:00:00',
'bio' => 'Professor and inventor of the Elvish Language'
),
'Book' => array(
'id' => '2',
'title' => 'Return of the King',
'pagecount' => '1200',
'publisher_id' => '1'
)
)
)
Now the question is - how can I fetch the associated model formed with a hasMany Through relationship without setting the recursive parameter?
Here's the source
<?php
class Author extends AppModel
{
public $hasMany = array('AuthorToBook');
}
?>
<?php
class AuthorToBook extends AppModel
{
public $useTable = 'authors_to_books';
public $belongsTo = array('Author', 'Book');
}
?>
<?php
class Book extends AppModel {
public $hasMany = array('AuthorToBook');
}
?>
Containable Behavior is your friend and is THE replacement for recursive. It allows you to specify exactly which associated model(s) you want to retrieve with each query.
Recursive is a cool thing, but it's pretty much agreed that you shouldn't actually use it beyond doing the intro tutorial for CakePHP. Set public $recursive = -1; in your AppModel (which makes it off by default), and never look back.
I am working on a plugin for our CakePHP CMS that will handle blogs. When getting to the tags I needed to set the HABTM relationship to unique = false to be able add tags to a post without having to reset them all.
The BlogPost model looks like this
class BlogPost extends AppModel {
var $name = 'BlogPost';
var $actsAs = array('Core.WhoDidIt', 'Containable');
var $hasMany = array('Blog.BlogPostComment');
var $hasAndBelongsToMany = array('Blog.BlogTag' => array('unique' => false), 'Blog.BlogCategory');
}
The BlogTag model looks like this
class BlogTag extends AppModel {
var $name = 'BlogTag';
var $actsAs = array('Containable');
var $hasAndBelongsToMany = array('Blog.BlogPost');
}
The SQL error I am getting when I have the unique => true setting in the HABTM relationship between the BlogPost and BlogTag is
Query: SELECT `Blog`.`BlogTag`.`id`, `Blog`.`BlogTag`.`name`, `Blog`.`BlogTag`.`slug`, `Blog`.`BlogTag`.`created_by`, `Blog`.`BlogTag`.`modified_by`, `Blog`.`BlogTag`.`created`, `Blog`.`BlogTag`.`modified`, `BlogPostsBlogTag`.`blog_post_id`, `BlogPostsBlogTag`.`blog_tag_id` FROM `blog_tags` AS `Blog`.`BlogTag` JOIN `blog_posts_blog_tags` AS `BlogPostsBlogTag` ON (`BlogPostsBlogTag`.`blog_post_id` = 4 AND `BlogPostsBlogTag`.`blog_tag_id` = `Blog`.`BlogTag`.`id`)
As you can see it is trying to set the blog_tags table to 'Blog'.'BlogTag. which isn't a valid MySQL name.
When I remove the unique => true from the relationship it all works find and I can save one tag but when adding another it just erases the first one and puts the new one in its place.
Does anyone have any ideas? is it a bug or am I just missing something?
Cheers,
Dean
Dean
So do you have the tables blog_posts_blog_tags?
To quote the CakePHP literature on HABTM relationships
We'll need to set up an extra table in the database to handle HABTM associations. This new join table's name needs to include the names of both models involved, in alphabetical order, and separated with an underscore ( _ ).
So ( dropping the Blog bit for readability !) you need your posts tables, your tags table and your posts_tags table and then the HABTM definition is
class Post extends AppModel {
var $name = 'Post';
var $hasAndBelongsToMany = array(
'Tag' =>
array(
'className' => 'Tag',
'joinTable' => 'posts_tags',
'foreignKey' => 'post_id',
'associationForeignKey' => 'tag_id',
'unique' => true,
)
);
}