Вопрос

I have a model CommunityPartner with a has_and_belongs_to_many relationship with another model PartnerTag.

class CommunityPartner < ActiveRecord::Base
    VALID_EMAIL = /\A[\w+\-.]+@{1}[a-z\d\-.]+\.[a-z]+\z/i

    validates(:name, presence: true, uniqueness: true)
    validates(:email, presence: true, confirmation: true, 
                      format: { with: VALID_EMAIL })
    validates(:contact_method, presence: true)
    validates(:email_confirmation, presence: true)
    validates(:address, presence: true)
    validates(:phone_number, presence: true)
    validates(:description, presence: true)

    has_many(:projects, dependent: :destroy)
    has_and_belongs_to_many(:partner_tags)

    has_secure_password

    def create_tag_list(tag_list)
        tag_list.each do |tag|
            t = PartnerTag.new(name: tag.name)
            self.partner_tags << t
        end
    end
end

class PartnerTag < ActiveRecord::Base
    validates(:name, presence: true)

    has_and_belongs_to_many(:community_partners)
end

I've successfully created a form for a new partner, except for one thing: the partner's tags. I've created a method that creates the list of tags from an array. That array is made of a method that takes a string and separates it by spaces (it's in the controller below). How can I customize the params hash so that I can include a custom parameter from the form that is specifically for the string of tags? Alternatively, is there a better way to do this?

Here's the controller code:

class CommunityPartnersController < ApplicationController
    def index
        @all_partners = CommunityPartner.all
    end

    def new
        @new_partner = CommunityPartner.new
    end

    def create
        # create tag list from string passed in params[:community_partner][:pa    rtner_tags]
        # append each tag in list to partner instance
        @new_partner = CommunityPartner.new(allowed_community_partner_params)
        @new_partner.create_tag_list(parse_tags(params[:tags]))
        if(@new_partner.save)
            redirect_to(@new_partner)
        else
            render(:new)
        end
    end

    def edit
    end

    def show
        @partner = CommunityPartner.find(params[:id])
    end

    def update
    end

    def destroy
    end

    def parse_tags(tag_list)
        tag_list.split(/ /)
    end

    private

        def allowed_community_partner_params
            params.require(:community_partner).permit(:name, :email, 
                                   :display_email, :email_confirmation, :contact_method,
                                   :password, :password_confirmation, :phone_number,
                                   :address, :description)
    end
end
Это было полезно?

Решение

Sounds like you just need an attr_accessor in your CommunityPartner model. i.e.

class CommunityPartner < ActiveRecord::Base
   attr_accessor :tag_list
end

You can then add that attribute to your form and access it from params as params[:community_partner][:tag_list]. This would also cleanup your create_tag_list method as you would not need to pass a parameter. Remember to add :tag_list to your list of permitted attributes in the controller.

Другие советы

You could use a combination of the gems acts_as_taggable_on and chosen-rails to reduce user error (not including the space when separating tags.

Acts As Taggable On

Simple and maintained gem for adding tags to your Rails model.

Chosen Rails

Converts your textbox into a token based text box similar to how SO's tagging works.

https://github.com/tsechingho/chosen-rails

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top