尝试在Rails控制器中创建一个不从ActiveRecord / ApplicationRecord继承的对象,但是失败了

时间:2017-01-13 15:01:52

标签: ruby-on-rails ruby reactjs activerecord

我正在尝试在我的控制器代码中创建一个不从ActiveRecord继承的对象。该代码目前是我/lib目录中的直接子代。它的名字是post_type_specific_data_store.rb

class PostTypeSpecificDataStore
  attr_reader :post_type, :artists, :record_name, :series, :episode_name, :episode_number, :company, :product_name,
          :product_version

  def initialize(args={})
    @post_type = args.fetch(:post_type, nil)
    @artists = args.fetch(:artists, nil)
    @record_name = args.fetch(:record_name, nil)
    @series = args.fetch(:series, nil)
    @episode_name = args.fetch(:episode_name, nil)
    @episode_number = args.fetch(:episode_number, nil)
    @company = args.fetch(:company, nil)
    @product_name = args.fetch(:product_name, nil)
    @product_version = args.fetch(:product_version, nil)
  end
end

这是我当前的控制器代码,位于名为posts_controller.rb的文件中:

class PostsController < ApplicationController
  def index

  end

  def new
    if !current_user
      redirect_to root_path
    end
  end

  def create
    @post = Post.new(post_params)
    @post_type_specific_data_store = PostTypeSpecificDataStore.new(post_type_specifc_data_params)
    binding.pry
  end

  private
  def post_params
    params[:post][:author_id] = current_user.id
    params.require(:post).permit(:author_id, :excerpt, :body, :rating, :image_url, :post_type)
  end

  def post_type_specifc_data_params
    params.require(:post_type_specific_data)
          .permit(:postType, :artists, :recordName, :series, :episodeName, :episodeNumber, :company, :productName,
                  :productVersion)
  end
end

这是我目前的React / JSX前端代码:

class NewPost extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      postTypes: ["Music", "Anime", "Products"],
      currentPostType: null
    };
    this.choosePostType = this.choosePostType.bind(this);
    this.renderTypeSpecificFields = this.renderTypeSpecificFields.bind(this);
    this.renderCommonFields = this.renderCommonFields.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  choosePostType(type) {
    this.setState({currentPostType: type})
  }

  renderTypeSpecificFields() {
    let typeSpecificFields;
    if (this.state.currentPostType === "Music") {
      typeSpecificFields =
      <div>
        <input type="text" placeholder="Artists (Separate each one by a comma WITHOUT a space)" ref="artists" />
        <input type="text" placeholder="Record Name" ref="recordName" />
      </div>;
    } else if (this.state.currentPostType === "Anime") {
      typeSpecificFields =
      <div>
        <input type="text" placeholder="Series" ref="series" />
        <input type="text" placeholder="Episode Name" ref="episodeName" />
        <input type="number" min="1" name="Episode Number" ref="episodeNumber" />
      </div>;
    } else if (this.state.currentPostType === "Products") {
      typeSpecificFields =
      <div>
        <input type="text" placeholder="Company" ref="company" />
        <input type="text" placeholder="Product Name" ref="productName" />
        <input type="text" placeholder="Product Version" ref="productVersion" />
      </div>;
    }
    return typeSpecificFields;
  }

  renderCommonFields() {
    let commonFields =
    <div>
      <input type="text" placeholder="Excerpt" ref="excerpt" />
      <textarea placeholder="Body" ref="body"></textarea>
      <input type="number" min="1" max="7" name="Rating" ref="rating" />
      <input type="text" placeholder="Image URL" ref="imageURL" />
      <input type="submit" value="Create" />
    </div>
    return commonFields;
  }

  handleSubmit(event) {
    event.preventDefault();
    var post_type_specific_data = {};
    post_type_specific_data["postType"] = this.state.currentPostType;
    switch (this.state.currentPostType) {
      case "Music":
        let artists = this.refs.artists.value.split(",");
        post_type_specific_data["artists"] = artists;
        post_type_specific_data["recordName"] = this.refs.recordName.value;
        break;
      case "Anime":
        post_type_specific_data["series"] = this.refs.series.value;
        post_type_specific_data["episodeName"] = this.refs.episodeName.value;
        post_type_specific_data["episodeNumber"] = this.refs.episodeNumber.value;
        break;
      case "Products":
        post_type_specific_data["company"] = this.refs.company.value;
        post_type_specific_data["productName"] = this.refs.productName.value;
        post_type_specific_data["productVersion"] = this.refs.productVersion.value;
        break;
      default:
        break;
    }

    $.ajax({
      url: "/lepostnouveau",
      method: "POST",
      data: {
        post: {
          post_type: this.state.currentPostType,
          excerpt: this.refs.excerpt.value,
          body: this.refs.body.value,
          rating: this.refs.rating.value,
          image_url: this.refs.imageURL.value
        },
        post_type_specific_data
      }
    });
  }

  render() {
    return(
      <div>
        {
          this.state.postTypes.map((postType) => {
            let choosePostWithType = this.choosePostType.bind(this, postType);
            return(
              <PostTypeChooser key={postType}
                               type={postType}
                               choose={choosePostWithType} />
            )
          })
        }
        <form onSubmit={this.handleSubmit}>
          {this.renderTypeSpecificFields()}
          {this.renderCommonFields()}
        </form>
      </div>
    )
  }
}

最后,这是我得到的错误:

NameError: uninitialized constant PostsController::PostTypeSpecificDataStore

提前致谢!

1 个答案:

答案 0 :(得分:2)

您必须将lib文件夹添加到config/application.rb

中的自动加载路径
config.autoload_paths += %W(#{config.root}/lib)