3

I've migration tags_words

class CreateTagsWords < ActiveRecord::Migration
  def change
    create_table :tags_words, id: false do |t|
       t.references :tag
       t.references :word
     end
     add_index :tags_words, :tag_id
     add_index :tags_words, :word_id
  end
end

model words and tags:

class Word < ActiveRecord::Base
    attr_accessible :namelanguage1, :namelanguage2, :tags_attributes

    has_and_belongs_to_many :tags

    def self.search(search)
        if search
            find(:all, :conditions => ['namelanguage1 LIKE ?', "%#{search}%"])
        else
            find(:all)
        end
    end
end

class Tag < ActiveRecord::Base
    attr_accessible :name, :language_user_id

    has_and_belongs_to_many :words

    def self.search(search)
        if search
            find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
        else
            find(:all)
        end
    end
end

and when I'll add tags to words and then save it doesn't save in db (when I write in rails console Words.find(1).tags i get empty array.

henio180
  • 156
  • 1
  • 8

1 Answers1

2

You'd need to use the << ActiveRecord method to add to the respective collections you have:

#app/controllers/words_controller.rb
def add_tag
    word = Word.find(params[:id])
    tag = Tag.find(params[:id])

    word.tags << tag
end

Your problem will either be caused by you not saving your data correctly, or not calling it properly


Update

If you want to add tags to the word's tags collection after you've created a new word, you'll be able to do something like this:

#app/controllers/words_controller.rb
def create
    @word = Word.new(word_params)
    @word.save
end

private

def word_params
    params.require(:word).permit(:namelanguage1, :namelanguage2, tag_ids: [])
end

#app/models/word.rb
Class Word < ActiveRecord::Base
    attr_accessor :tag_ids
    after_create :add_tags

    def add_tags
       if tag_ids
           tag = Tag.find(tag_ids)
           tags << tag
       end
    end
end
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • I just started reading the question and you posted the answer. :/ – Kirti Thorat Mar 22 '14 at 11:46
  • It's not the answer - it's just a recommendation. The OP should post updates about how they're modifying the collections. You should still provide input - it will help them out – Richard Peck Mar 22 '14 at 11:46
  • I've added this method but i dont'n know how to call it?? – henio180 Mar 22 '14 at 11:49
  • BTW you can try is in the console - just do this: `word = Word.find(1)` `tag = Tag.find(1)` `word << tag` `word.tags` – Richard Peck Mar 22 '14 at 11:53
  • Thanks - where would you like to add new tags to a word? (which method)? – Richard Peck Mar 22 '14 at 11:57
  • when i create new word – henio180 Mar 22 '14 at 11:58
  • Okay, and which tags would you like to add to the collection? – Richard Peck Mar 22 '14 at 12:02
  • Okay thanks, you'd normally use `accepts_nested_attributes_for` with this, but can only be used with `has_many :through`. Otherwise, we'd need to call the after_create method & use some virtual params – Richard Peck Mar 22 '14 at 12:10
  • could you explain me how I can fix it?? I started my adventure with rails – henio180 Mar 22 '14 at 12:12
  • Updated for you - you'll have to use `after_create` with virtual attributes. Because you're using Rails 3, I think my code will need tweaking, but it should be okay – Richard Peck Mar 22 '14 at 12:13
  • You've got to provide some more info man - can you use the Rails logger or something/ – Richard Peck Mar 22 '14 at 12:33
  • Unpermitted parameters: tag_ids (0.2ms) begin transaction SQL (0.7ms) INSERT INTO "words" ("created_at", "namelanguage1", "namelanguage2", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sat, 22 Mar 2014 12:33:43 UTC +00:00], ["namelanguage1", "fhjikhki"], ["namelanguage2", "hkhgjk"], ["updated_at", Sat, 22 Mar 2014 12:33:43 UTC +00:00]] – henio180 Mar 22 '14 at 12:35
  • I'm using Rails 4.0.3 – henio180 Mar 22 '14 at 12:37
  • Good - let me update my answer. BTW your use of `attr_accessible` is only valid for Rails 3 – Richard Peck Mar 22 '14 at 12:38
  • but when i delete it i can't add anything to db – henio180 Mar 22 '14 at 12:39
  • Because you need to use Strong Params to create the correct item :) – Richard Peck Mar 22 '14 at 12:40
  • "Missing template words/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in: * "/home/henio/Desktop/wordsy/app/views"" – henio180 Mar 22 '14 at 12:48
  • You'll need to create the `/views/words/create.html.erb` file ;) – Richard Peck Mar 22 '14 at 12:49
  • Error /logs? You need to be more specific! It's a logical process - if it doesn't work, there'll be a problem somewhere :) I can only use what you provide so you need to provide more details – Richard Peck Mar 22 '14 at 12:54
  • WARNING: Can't mass-assign protected attributes for Word: tag_ids app/controllers/words_controller.rb:30:in `create' – henio180 Mar 22 '14 at 12:57
  • hmmm okay thanks for this. This issue will either be caused by the `protected_attributes` gem, or because `tag_ids` is used by another process. Do you have the `protected_attributes` gem in your GemFile? – Richard Peck Mar 22 '14 at 12:58
  • Yes i have gem 'protected_attributes' – henio180 Mar 22 '14 at 12:59
  • Do you need it for anything else? – Richard Peck Mar 22 '14 at 12:59
  • I have user authentication and i use it with gem "bcrypt-ruby", :require => "bcrypt" - i think that – henio180 Mar 22 '14 at 13:01
  • Homebrewed authentication? Are you following the Hartl tutorial? Protected Attributes is depreciated in Rails 4, but can work around it if you need – Richard Peck Mar 22 '14 at 13:04
  • I make authentication with this [tutorial](http://railscasts.com/episodes/250-authentication-from-scratch) but if i can make it easier i'll if you say me how – henio180 Mar 22 '14 at 13:05
  • OK i changed this and now I have "Couldn't find all Tags with IDs (, 10) (found 1 results, but was looking for 2)" – henio180 Mar 22 '14 at 13:08
  • You'd be much better using [Devise](http://railscasts.com/episodes/209-introducing-devise)! You'll have to replace your homebrewed authentication though :( – Richard Peck Mar 22 '14 at 13:08
  • Nice, this is very very very good news - it means our callback is working. How are you selecting the IDs? One of them is not being sent – Richard Peck Mar 22 '14 at 13:09
  • Words view:

    <%= f.label :tags %>
    <%= f.collection_select :tag_ids, @all_tags, :id, :name, {}, { :multiple => true } %>

    – henio180 Mar 22 '14 at 13:10
  • can you try removing `:multiple` for now? This will send a single ID, which will hopefully send the correct data – Richard Peck Mar 22 '14 at 13:11
  • I get now: "Unpermitted parameters: tag_ids" – henio180 Mar 22 '14 at 13:13
  • Wow okay... did you change any other code? It passed the correct params last time – Richard Peck Mar 22 '14 at 13:14
  • CAn you show which params it's sending in the logs? -> `params{}` – Richard Peck Mar 22 '14 at 13:14
  • Parameters: {"utf8"=>"✓", "authenticity_token"=>"74Mhbpn9FF/tY/cgfuVmX7ribN4rOkkdUjSgbLNsces=", "word"=>{"namelanguage1"=>"dfdd", "namelanguage2"=>"ddd", "tag_ids"=>"10"}, "button"=>""} – henio180 Mar 22 '14 at 13:14
  • And your strong params code is the same? You've not changed it? Where does the unpermitted params error happen - controller or model? – Richard Peck Mar 22 '14 at 13:17
  • 1
    Now i change: def word_params params.require(:word).permit(:namelanguage1, :namelanguage2, :tag_ids) end Ant it's work :D But how can I use multiple? – henio180 Mar 22 '14 at 13:19
  • For multiple, you'll have to change strong_params back to accepting array, and it will be to work with the `multiple` select element - what were you doing before to return a blank ID? – Richard Peck Mar 22 '14 at 13:21
  • OK i changed to params.require(:word).permit(:namelanguage1, :namelanguage2, tag_ids: []) and I get the same problem: Couldn't find all Tags with IDs (, 10, 11) (found 2 results, but was looking for 3) – henio180 Mar 22 '14 at 13:25
  • Okay, we are making progress. What are you doing to make the first element null in your selector? Are you doing anything strange? – Richard Peck Mar 22 '14 at 13:27
  • Now i see in logs: Parameters: {"utf8"=>"✓", "authenticity_token"=>"74Mhbpn9FF/tY/cgfuVmX7ribN4rOkkdUjSgbLNsces=", "word"=>{"namelanguage1"=>"dfgd", "namelanguage2"=>"dddd", "tag_ids"=>["", "10", "11"]}, "button"=>""} – henio180 Mar 22 '14 at 13:28
  • No I do nothing with empty element – henio180 Mar 22 '14 at 13:29
  • Yes - this is fine. The problem is `[""` -- if we can make it so your HTML does not send blank element, the thing should work – Richard Peck Mar 22 '14 at 13:29
  • http://stackoverflow.com/questions/8929230/why-is-the-first-element-always-blank-in-my-rails-multi-select-using-an-embedde it's a common problem – Richard Peck Mar 22 '14 at 13:31
  • 1
    OK i write it in this way: tag = Tag.find(tag_ids.to_a.drop(1)) an it's work :D thank you very very very very much for your help. – henio180 Mar 22 '14 at 13:38
  • Np! You should accept my answer & upvote if it works ;) – Richard Peck Mar 22 '14 at 13:48
  • I've accepted your answer but i can't vote up because i don't have enough reputation :( – henio180 Mar 22 '14 at 14:01
  • Lol one of the ironies of SO! I thank you for upvote & hope you continue to make great apps in Rails :) – Richard Peck Mar 22 '14 at 14:02
  • Thank you - I just started Rails and I like it ;) – henio180 Mar 22 '14 at 14:04
  • 1
    +1 for the dedication and the solution of course. :) – Kirti Thorat Mar 22 '14 at 19:30